TGViewer
FAANG Master FAANG Master @faangmaster · 2.94K subscribers
Post #270 1.82K
Вопрос с собеседования на Java программиста: Какую коллекцию вы бы использовали в качестве Hash-таблицы в многопоточной среде и почему?

Это вопрос может иметь различную формулировку:
1) Какую коллекцию вы бы использовали в качестве Hash-таблицы в многопоточной среде и почему?
2) Что такое ConcurrentHashMap?
3) В чем преимущества ConcurrentHashMap?
4) Как работает ConcurrentHashMap?
5) В чем отличия HashMap, Collections.synchronizedMap(map), ConcurrentHashMap, Hashtable?

Ответ. В однопоточной среде можно использовать HashMap или LinkedHashMap (если надо сохранить порядок добавления элементов при итерировании). Смотрите мою статью про Map: Иерархия Map, HashMap.
Но даже в однопоточной среде мы может получить проблему в виде ConcurrentModificationException. Смотрите мою статью: ConcurrentModificationException. Дело в том, что итераторы реализуют стратегию fail-fast для не потокобезопасных коллекций. Если во время итерирования по коллекции (в данном случае по HashMap) мы произведем модификацию этой коллекции в том же потоке или в другом, то итератор в какой-то момент это обнаружит и бросит ConcurrentModificationException.
Например, такой код бросит ConcurrentModificationException даже в однопоточной среде:
Map<String, String> map = new HashMap<>() {
{
put("foo", "val1");
put("bar", "val2");
}
};
for (String key : map.keySet()) {
map.remove("bar");
}

Для этого в однопоточной среде удаление нужно делать не напрямую методом remove, а с использованием итератора (map.entrySet().iterator(); iterator.remove();). А чтобы использовать HashMap в многопоточной среде, нужно использовать synchronized или локи перед тем как взаимодействовать с hash-таблицей. Причем, как перед модификациями, так и перед чтением, так и перед итерированиями, в том числе не явными.
Другой доступный вариант - это сделать все методы HashMap synchronized при помощи обертки:
Collections.synchronizedMap(new HashMap<>());

Но тут тоже надо помнить, что перед итерированием нужно получить лок на всей коллекции, иначе можем получить ConcurrentModficicationException.
Т.к. Collections.synchronizedMap() оборачивает все методы в synchronized, то методы put и get становятся блокирующими и только один поток может взаимодействовать в этой hash-таблицей одновременно, все остальные потоки, которые вызвали блокирующие методы будут ждать завершения операции. Это может ухудшить производительность вашей многопоточной программы.
Аналогичная ситуация и с классом Hashtable. У него также методы synchronized. И использование этой коллекции также может повлиять на производительность, а также не спасает по умолчанию от ConcurrentModficicationException без дополнительных локов.
Поэтому рекомендуется рассмотреть ConcurrentHashMap коллекцию. Она использует другой подход к блокированию коллекции под названием lock striping. Это позволяет не блокировать всю коллекцию. Множество потоков могут одновременно читать из коллекции параллельно, не ожидая друг друга. Более того, потоки, которые пишут и которые читают из коллекции, также могут получить параллельный доступ. Что еще круче - итераторы weakly consistent вместо fail-fast. Это предотвращает ConcurrentModficicationException при итерировании, но вы можете видеть не самые актуальные данные при итерировании. Более того, при чтении из коллекции вы будете видеть значение после последней завершенной операции записи. Если уже была инициированна другая операция записи, то вы можете при параллельном чтении не увидеть это значение. Это позволяет использовать ConcurrentHashMap более безопасно в многопоточной среде и получить существенно лучшую производительность. Но если нам нужна функциональность эксклюзивного доступа и более строкой консистенции данных, то она вам не подойдет.
Oracle HashMap (Java SE 20 & JDK 20) declaration: module: java.base, package: java.util, class: HashMap
  • 👍 19
  • ❤ 7
More from @faangmaster
  1. Sep 13, 2026Навье-Стоксгейт 8 сентября OpenAI заявила, что её невыпущенная модель решила одну из семи…
  2. Sep 3, 2026Uber совместно с британским стартапом Wayve запускает роботакси в Лондоне Пришла нотификац…
  3. Aug 20, 2026Новый HTTP метод QUERY Этим летом в спецификацию HTTP добавили новый метод - QUERY. Добавл…
  4. Aug 15, 2026IOI 2026 В Ташкенте прошел межнар школьников по информатике. Результаты: https://stats.ioi…
  5. Jul 30, 2026В свое время я закончил МФТИ. Относительно непростой вуз для обучения. Закончил неплохо. З…
  6. Jul 18, 2026Документалка про Java В продолжение темы документалок, вышла документалка про Java. Трейле…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →