Ответ
Да, метод put() в ConcurrentHashMap является потокобезопасным. Он позволяет нескольким потокам безопасно модифицировать карту одновременно.
Как это работает:
- В версиях до Java 8 используется сегментированная блокировка (lock striping), где блокируется только отдельный сегмент (бакет).
- Начиная с Java 8, для большинства операций применяются оптимистичные блокировки на основе CAS (Compare-And-Swap) и
synchronizedна уровне отдельного узла (ноды) бакета, что повышает параллелизм.
Пример использования:
ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();
// Потокобезопасные операции из разных потоков:
concurrentMap.put("keyA", 100);
concurrentMap.put("keyB", 200);
Важные нюансы:
- Атомарность: Гарантируется атомарность одиночных операций (
put(),get(),remove()). - Составные операции: Операции типа "проверить и вставить" (check-then-act) не являются атомарными при использовании отдельных вызовов. Для них следует использовать специальные методы, такие как
putIfAbsent(),compute(),merge(). - Итераторы: Итераторы, получаемые от
ConcurrentHashMap(например, черезentrySet().iterator()), являются слабо согласованными (weakly consistent). Они не бросаютConcurrentModificationExceptionи могут отражать лишь часть изменений, произошедших после их создания. - null-значения:
ConcurrentHashMapне разрешает использованиеnullв качестве ключа или значения.