Сколько сегментов создаётся в ConcurrentHashMap по умолчанию?

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

Ответ

Архитектура ConcurrentHashMap (CHM) различается между версиями Java:

  • Java 7 и ранее: Используется модель сегментов (lock-striping). По умолчанию создаётся 16 сегментов (каждый со своей блокировкой). Количество можно задать через параметр concurrencyLevel в конструкторе.
  • Java 8 и выше: Архитектура изменена. Вместо сегментов используется массив узлов (Node[] table) с блокировками на уровне отдельных бакетов (ячеек). Параметр concurrencyLevel остаётся для совместимости, но является лишь подсказкой для начального размера.

Пример и сравнение:

// Java 7: Внутри 16 сегментов (Segment[])
// Java 8+: Lock-striping на уровне бакетов (synchronized на первом узле бакета)
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

// Конструктор с параметром concurrencyLevel (актуален для Java 7)
ConcurrentHashMap<String, Integer> map2 = new ConcurrentHashMap<>(16, 0.75f, 32);

Ключевое изменение в Java 8+: Использование CAS-операций и тонких блокировок значительно повышает степень параллелизма по сравнению с моделью фиксированных сегментов.