Ответ
Для сценария «частое чтение, редкая запись» оптимальным выбором является CopyOnWriteArrayList (или CopyOnWriteArraySet).
Принцип работы (Copy-On-Write):
- Все операции чтения (
get,iterator,forEach) работают с неизменяемым «снимком» (snapshot) внутреннего массива без блокировок. - Каждая операция модификации (
add,set,remove) создает новую копию базового массива, что делает ее дорогой, но безопасной.
Пример использования:
// Инициализация потокобезопасного списка
CopyOnWriteArrayList<String> configList = new CopyOnWriteArrayList<>();
// Редкое обновление (дорогая операция)
configList.add("NewConfigParameter");
// Частое чтение (дешевая операция, без блокировок)
String value = configList.get(0);
// Потокобезопасная итерация по snapshot
for (String config : configList) {
System.out.println(config);
}
Преимущества:
- ✔️ Максимальная производительность при чтении.
- ✔️ Полная потокобезопасность для итераторов (нет
ConcurrentModificationException). - ✔️ Простой API.
Недостатки и ограничения:
- ❌ Высокая стоимость операций записи из-за копирования массива.
- ❌ Может привести к повышенному потреблению памяти при частых модификациях.
- ❌ Данные, прочитанные итератором, могут быть устаревшими (snapshot semantics).
Типичные use-cases: списки слушателей (listeners), кэши конфигураций, rarely-updated lookup-таблицы.