👀 Внутреннее устройство CopyOnWriteArrayList
CopyOnWriteArrayList — это потокобезопасная коллекция из пакета java.util.concurrent, которая реализует интерфейсы List и RandomAccess. Она часто воспринимается как «волшебная таблетка» для многопоточности, но под капотом это хитрая стратегия: каждое изменение списка создаёт копию массива.
📦 Базовая структура
Внутри CopyOnWriteArrayList хранит данные в обычном массиве
— Все операции чтения (get, iterator, contains) идут напрямую по этому массиву и не требуют синхронизации.
— При модификациях (add, remove, set) создаётся новый массив с учётом изменений, и ссылка array указывает на него.
За счёт этого чтения не блокируются, а итераторы всегда видят снимок состояния (snapshot) на момент создания.
⚡️ Добавление и удаление
— add(E e): берётся текущий массив, копируется в новый на +1 элемент, в конец добавляется e.
— remove(Object o): копия массива создаётся без указанного элемента.
— set(int index, E element): создаётся копия массива, в которой меняется один элемент.
Сложность таких операций — O(n), ведь нужно копировать массив.
🌊 Итераторы
— Итератор у CopyOnWriteArrayList не fail-fast, в отличие от ArrayList и LinkedList.
— Он работает по «снимку» массива, который существовал в момент вызова iterator().
— Изменения, сделанные другими потоками, в процессе обхода не видны.
📊 Производительность
— Чтение (get, contains, iteration) → O(1) / O(n) для поиска очень быстро, так как обращение к массиву.
— Запись (add, remove, set) → O(n), так как требуется копировать массив.
— Итерация → O(n), но без блокировок и с высокой стабильностью в многопоточной среде.
⚖️ Важные нюансы
— CopyOnWriteArrayList идеален для сценариев «много чтений, мало записей».
— Память расходуется щедро: каждый апдейт порождает новую копию массива.
— Если записи происходят часто, использование становится неоправданным.
🧮 Когда использовать
— Подписчики/слушатели событий (например, listeners в UI или логгере).
— Кэш статических данных, где обновления редки.
— Конфигурации, которые меняются редко, а читаются часто.
В большинстве остальных случаев лучше использовать другие структуры (ConcurrentHashMap, Collections.synchronizedList, CopyOnWriteArraySet).
🔗 Документация: официальная JavaDoc (Java 17)
Ставьте 🔥, если хотите такой же пост по другим коллекциям. Пишите в комменты, какую коллекцию разобрать следующей.
🐸 Библиотека джависта
#CoreJava
CopyOnWriteArrayList — это потокобезопасная коллекция из пакета java.util.concurrent, которая реализует интерфейсы List и RandomAccess. Она часто воспринимается как «волшебная таблетка» для многопоточности, но под капотом это хитрая стратегия: каждое изменение списка создаёт копию массива.
📦 Базовая структура
Внутри CopyOnWriteArrayList хранит данные в обычном массиве
transient volatile Object[] array
.— Все операции чтения (get, iterator, contains) идут напрямую по этому массиву и не требуют синхронизации.
— При модификациях (add, remove, set) создаётся новый массив с учётом изменений, и ссылка array указывает на него.
За счёт этого чтения не блокируются, а итераторы всегда видят снимок состояния (snapshot) на момент создания.
⚡️ Добавление и удаление
— add(E e): берётся текущий массив, копируется в новый на +1 элемент, в конец добавляется e.
— remove(Object o): копия массива создаётся без указанного элемента.
— set(int index, E element): создаётся копия массива, в которой меняется один элемент.
Сложность таких операций — O(n), ведь нужно копировать массив.
🌊 Итераторы
— Итератор у CopyOnWriteArrayList не fail-fast, в отличие от ArrayList и LinkedList.
— Он работает по «снимку» массива, который существовал в момент вызова iterator().
— Изменения, сделанные другими потоками, в процессе обхода не видны.
📊 Производительность
— Чтение (get, contains, iteration) → O(1) / O(n) для поиска очень быстро, так как обращение к массиву.
— Запись (add, remove, set) → O(n), так как требуется копировать массив.
— Итерация → O(n), но без блокировок и с высокой стабильностью в многопоточной среде.
⚖️ Важные нюансы
— CopyOnWriteArrayList идеален для сценариев «много чтений, мало записей».
— Память расходуется щедро: каждый апдейт порождает новую копию массива.
— Если записи происходят часто, использование становится неоправданным.
🧮 Когда использовать
— Подписчики/слушатели событий (например, listeners в UI или логгере).
— Кэш статических данных, где обновления редки.
— Конфигурации, которые меняются редко, а читаются часто.
В большинстве остальных случаев лучше использовать другие структуры (ConcurrentHashMap, Collections.synchronizedList, CopyOnWriteArraySet).
Ставьте 🔥, если хотите такой же пост по другим коллекциям. Пишите в комменты, какую коллекцию разобрать следующей.
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍3👏1