Ответ
Работал с коллекциями из пакета java.util.concurrent, каждая из которых решает конкретные проблемы параллелизма.
Основные коллекции и их применение:
| Коллекция | Принцип работы | Лучший сценарий использования |
|---|---|---|
ConcurrentHashMap |
Сегментирование (bucket-level locking) или CAS для Java 8+. | Высококонкурентные put/get операции. Кэши, shared-словари. |
CopyOnWriteArrayList / CopyOnWriteArraySet |
Создание новой копии массива при каждой модификации. | Частое чтение, редкая запись (Listener-списки, конфигурации). |
ConcurrentLinkedQueue |
Неблокирующая очередь на основе CAS (Compare-And-Swap). | Высокопроизводительная очередь без ограничения размера. |
BlockingQueue (напр., ArrayBlockingQueue, LinkedBlockingQueue) |
Блокирует поток при попытке взять из пустой или положить в полную очередь. | Паттерн Producer-Consumer, пулы соединений. |
ConcurrentSkipListMap / ConcurrentSkipListSet |
Потокобезопасная реализация на основе skip-list. | Когда нужна отсортированная потокобезопасная коллекция. |
Пример Producer-Consumer с BlockingQueue:
BlockingQueue<Message> queue = new LinkedBlockingQueue<>(100);
// Producer поток
public void run() {
queue.put(new Message("data")); // Блокируется, если очередь полна
}
// Consumer поток
public void run() {
Message msg = queue.take(); // Блокируется, если очередь пуста
process(msg);
}
Важные замечания:
- Итераторы
ConcurrentHashMapиConcurrentLinkedQueueявляются слабо согласованными (weakly consistent) и не бросаютConcurrentModificationException. - Атомарные составные операции (например,
putIfAbsent,computeIfAbsent) вConcurrentHashMapбезопасны и часто более эффективны, чем внешняя синхронизация. CopyOnWriteArrayListможет быть дорогим по памяти при частых записях, но обеспечивает полную безопасность итераторов.