Ответ
Прямой потокобезопасный аналог ArrayList в пакете java.util.concurrent — CopyOnWriteArrayList.
Принцип работы:
При каждой операции модификации (add, set, remove) создается новая копия внутреннего массива. Это обеспечивает безопасность итераторов (они работают с неизменяемым снимком), но делает операции записи затратными.
Пример использования:
import java.util.concurrent.CopyOnWriteArrayList;
List<String> concurrentList = new CopyOnWriteArrayList<>();
// Поток 1
concurrentList.add("Element1");
// Поток 2 (итерация безопасна, даже если список изменяется)
for (String item : concurrentList) {
System.out.println(item); // Нет ConcurrentModificationException
}
Когда использовать CopyOnWriteArrayList:
- Частое чтение, очень редкая запись. (Например, список слушателей событий).
- Когда размер коллекции небольшой, чтобы стоимость копирования была приемлемой.
- Когда критически важна безопасность итераторов.
Альтернативы для других сценариев:
Collections.synchronizedList(new ArrayList<>())- Подходит для более сбалансированной нагрузки чтение/запись.
- Требует ручной синхронизации при итерации!
List<String> syncList = Collections.synchronizedList(new ArrayList<>()); // При итерации нужно синхронизировать synchronized(syncList) { for (String s : syncList) { /* ... */ } }
ConcurrentLinkedQueue— если нужна потокобезопасная очередь (FIFO).
Вывод: CopyOnWriteArrayList — специализированная реализация для сценариев «чтение-много, запись-мало». Для общего случая synchronizedList или другие concurrent-коллекции могут быть эффективнее.