Мне нужно сохранить некоторые объекты в базе данных.
Прежде всего,
Так,
public class AuditService {
private CopyOnWriteArrayList<Audit> copyWrite;
public void flush(Audit... audits) {
Collection<Audit> auditCollection = Arrays.asList(audits);
this.copyWrite.addAll(auditCollection);
this.copyWrite.forEach(audit -> {
// save audit object on database
this.copyWrite.remove(audit);
});
}
}
Я должен быть потокобезопасным, я имею в виду, что AuditService - это одноэлементный класс, я могу одновременно использовать несколько потоков в методе flush.
У меня вопрос:
CopyOnWriteArrayList, чтобы решить проблему параллелизма.



CopyOnWriteArrayList обеспечивает безопасность потоков, копируя базовый массив при изменении данных. Операции мутатора, такие как addAll() в вашем примере, внутренне синхронизируются CopyOnWriteArrayList.
Однако ваш код не имеет особого смысла, поскольку доступ к полю copyWrite не осуществляется вне метода flush(). Переменные локального метода являются потокобезопасными, поэтому ваш код можно упростить до простого:
public void flush(Audit... audits) {
for (Audit a : audits) {
// save audit object on database
}
}
Проблема в том, что произойдет, если объект Audit будет изменен. Надеюсь, вы сделали их неизменяемыми, поскольку нет смысла изменять события Audit.
В этом мало смысла, если вы не ожидаете, что сервер базы данных выйдет из строя больше, чем сервер приложений. Обычно все наоборот. Возможно, я не понимаю вашего пейзажа.
Вы предлагаете мне другую стратегию?
Возможно ли, чтобы один и тот же объект аудита, хранящийся в CopyOnWriteArrayList, дважды сохранялся в базе данных?
Я имею в виду, что происходит, когда два потока достигают forEach? Собираются ли оба потока «перечислять» одни и те же аудиты, и тогда один и тот же аудит может быть сохранен дважды ...?
@Jordi, в этом случае вы, скорее всего, захотите использовать ограничения базы данных для дедупликации. В вашем текущем подходе Java нет логики деэпультации, и он не будет работать, если вы развернете свое приложение дважды и у вас будет более одной JVM. Вероятно, вам следует задать здесь новый вопрос, он не имеет ничего общего с CopyOnWriteArrayList.
Аудиты сначала сохраняются на
CopyOnWriteArrayList, поскольку в случае отказаsave audit on database operationв следующий раз, когда будет достигнутflush, ожидающие аудиты будут снова попытки сохранения. О чем вы думаете.