Чем HashMap отличается от Hashtable и ConcurrentHashMap?
- Можно ли использовать HashMap из нескольких потоков?
HashMap — не потокобезопасна, допускает один null-ключ и null-значения. Hashtable — устаревшая, все методы synchronized, null запрещён. ConcurrentHashMap — потокобезопасная с мелкой блокировкой, null запрещён.
- Однопоточно или под внешней синхронизацией — HashMap
- Конкурентный доступ — ConcurrentHashMap
- Hashtable в новом коде не нужна
А ещё Параллельная запись в HashMap может потерять данные и испортить структуру
Подробно
| HashMap | Hashtable | ConcurrentHashMap | |
|---|---|---|---|
| потокобезопасность | нет | да, один замок | да, замок на корзину и CAS |
| null-ключ / значения | один ключ, значения да | нет | нет |
| итератор | fail-fast | fail-fast (Enumeration — нет) | weakly consistent |
| появилась | Java 1.2 | Java 1.0 | Java 5 |
HashMap из нескольких потоков: одновременные put теряют записи, а при расширении таблицы данные могут оказаться в неверных корзинах (до Java 8 — даже бесконечный цикл в цепочке). Безопасно только чтение карты, которая больше не меняется и была безопасно опубликована.
Hashtable — класс из Java 1.0: synchronized на каждом методе, итерация через Enumeration, null запрещены. Медленнее ConcurrentHashMap под конкуренцией и не даёт атомарных составных операций.
ConcurrentHashMap — выбор для общего кэша, счётчиков (merge(key, 1, Integer::sum)), реестров. Итератор не бросает ConcurrentModificationException и может видеть часть параллельных изменений.
Что хотят услышать
- Различия в потокобезопасности и null.
- Что произойдёт при конкурентной записи в HashMap.
- Практический выбор.
Частые ошибки
- Считать Hashtable лучшим выбором для многопоточности.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Все три потокобезопасны одинаково
- ✓HashMap несинхронизирован, Hashtable блокирует целиком, ConcurrentHashMap — по бакетам
- ✗HashMap синхронизирован, Hashtable — нет, ConcurrentHashMap копирует таблицу
- ✗ConcurrentHashMap медленнее Hashtable
Что спросят дальше
- Что такое fail-fast iterator?
- Почему ConcurrentHashMap запрещает null?
Разбор темы
- Конкурентные коллекции
ConcurrentHashMap без сегментов (CAS + блокировка бакета), запрет null, CopyOnWriteArrayList и BlockingQueue.
- HashMap изнутри: бакеты, treeify, resize
Таблица бакетов, перемешивание хеша и индекс, превращение цепочки в дерево, ресайз и load factor, контракт ключа.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.