Что такое ConcurrentHashMap в Java и чем он отличается от Hashtable?

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

Ответ

ConcurrentHashMap — это потокобезопасная реализация интерфейса Map, оптимизированная для высокого параллелизма при операциях чтения и записи.

Ключевые отличия от Hashtable и Collections.synchronizedMap():

Особенность Hashtable / synchronizedMap ConcurrentHashMap
Блокировка Глобальная блокировка на весь объект (монопольная) Сегментированная блокировка (блокируется только bucket или узел)
Чтение Блокирует все потоки Не блокирует (чтение может происходить параллельно с записью)
Итератор ConcurrentModificationException при изменении Слабая согласованность (weakly-consistent): итератор отражает состояние на момент создания и может не показывать последующие изменения, но не бросает исключений.
Производительность Низкая при высокой конкуренции Высокая, особенно при частых чтениях.

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

ConcurrentHashMap<String, Integer> scores = new ConcurrentHashMap<>();

// Атомарная операция "добавить если отсутствует"
scores.putIfAbsent("Alice", 100);

// Атомарное обновление значения
scores.compute("Alice", (key, oldVal) -> oldVal == null ? 1 : oldVal + 10);

Почему сегментирование эффективно: Оно позволяет множеству потоков работать с разными частями (сегментами) карты одновременно, что резко снижает contention (конкуренцию за блокировку). Начиная с Java 8, вместо сегментов используется оптимистичная блокировка на уровне отдельных узлов (CAS-операции) для еще большей производительности.