Почему ConcurrentHashMap быстрее synchronized-обёртки
Оба варианта потокобезопасны, но ведут себя по-разному под нагрузкой. Collections.synchronizedMap вешает один монитор на всю карту: читатели блокируют друг друга, хотя ничего не меняют.
ConcurrentHashMap синхронизирует по бакетам и не блокирует чтение вовсе.
Map counts = new ConcurrentHashMap<>();
counts.merge(key, 1, Integer::sum);
Что спросят следом Почему get не требует блокировки? Значения в узлах объявлены volatile, поэтому запись публикуется корректно и читатель видит свежие данные без монитора.
Ответ, который ждут на собесе: по-бакетная синхронизация вместо одной большой блокировки