Что такое ConcurrentHashSet в Java и как его создать?

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

Ответ

ConcurrentHashSet — это потокобезопасная (thread-safe) реализация интерфейса Set в Java. Прямого класса ConcurrentHashSet в стандартной библиотеке JDK нет, но его легко создать на основе ConcurrentHashMap, используя статический фабричный метод.

Способ создания (рекомендуемый):

import java.util.Set;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;

// Создание потокобезопасного множества
Set<String> concurrentSet = Collections.newSetFromMap(
    new ConcurrentHashMap<>()
);

// Использование
concurrentSet.add("value1");
concurrentSet.contains("value1"); // true

Альтернатива (с Java 8+): Можно использовать ConcurrentHashMap.newKeySet().

Set<String> concurrentSet = ConcurrentHashMap.newKeySet();
concurrentSet.add("value2");

Характеристики и особенности:

  • Потокобезопасность: Обеспечивается за счёт внутренней реализации ConcurrentHashMap (сегментирование или CAS-операции в новых версиях).
  • Производительность: Высокая степень параллелизма для операций add, remove, contains.
  • Слабосогласованные итераторы (weakly consistent): Итератор отражает состояние множества на момент его создания или может показывать часть последующих изменений, но никогда не выбросит ConcurrentModificationException.
  • Порядок элементов: Не гарантируется.
  • Null-значения: Не разрешены, так как базовая ConcurrentHashMap не поддерживает null в качестве ключа.
  • Отсутствие блокировок: Операции чтения не блокируются, большинство операций записи используют эффективные lock-free или fine-grained блокировки.