Какие потокобезопасные коллекции существуют в Java?

«Какие потокобезопасные коллекции существуют в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Java потокобезопасные коллекции представлены в основном в пакете java.util.concurrent. Они используют продвинутые lock-free или fine-grained блокировки, что обеспечивает высокую производительность в многопоточных сценариях.

Основные реализации:

  • ConcurrentHashMap<K,V> — потокобезопасный аналог HashMap. Сегментирует данные, блокируя не всю таблицу, а только отдельный сегмент (bucket) при изменении.
  • CopyOnWriteArrayList<E> — список, где каждая модификация создаёт новую копию внутреннего массива. Идеален для часто читаемых, редко изменяемых данных.
  • CopyOnWriteArraySet<E> — реализация Set на основе CopyOnWriteArrayList.
  • ConcurrentLinkedQueue<E> — неблокирующая (lock-free) очередь на основе связанных узлов.
  • ConcurrentSkipListMap<K,V> / ConcurrentSkipListSet<E> — отсортированные аналоги TreeMap/TreeSet.
  • BlockingQueue интерфейс и его реализации (ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue) — очереди с поддержкой блокирующих операций put и take.

Пример использования ConcurrentHashMap:

import java.util.concurrent.ConcurrentHashMap;

ConcurrentHashMap<String, Integer> scores = new ConcurrentHashMap<>();
// Безопасные операции из разных потоков:
scores.put("Alice", 10);
scores.compute("Bob", (k, v) -> (v == null) ? 1 : v + 1); // Атомарное обновление

Устаревший подход: Collections.synchronizedList(new ArrayList<>()) создаёт коллекцию с глобальной блокировкой (все методы синхронизированы). Это проще, но менее производительно при высокой конкуренции, чем специализированные коллекции из java.util.concurrent.