Комментарии 7
Подвох №1 несправедлив для ConcurrentHashMap, т.к. (из документации) «the function is applied at most once per key»
"условие ожидания — Condition await()/signal(). С synchronized это недоступно. " - а как же wait и notify?
В последнем примере, пока один поток будет висеть в выполнении calculateExpensive(key), ничего не мешает другим потокам тоже получить null в get и тоже упасть в вычисление. Тогда уже лучше использовать computeIfAbsent, который гарантирует только один вызов на ключ, судя по документации, а то, что кто-то в лямбду добавляет side-effectы, это уже проблема не ConcurrentHashMap, а разработчика. Да и не вижу в чем проблема долгих исчислений, это не блокирует всю таблицу, проблема лишь в том, что поток занят и наверное нужно вообще переосмысливать идею пользоваться лишь одной таблицой для приложений с высокой нагрузкой.
Всю таблицу конечно не блокирует, но корзину блокирует.
(из документации) Some attempted update operations on this map by other threads may be blocked while computation is in progress.
И при высокой конкурентности обновлений могут быть взаимные блокировки на разных ключах, что особо чувствительно при «прогреве» кешей, основанных на ConcurrentHashMap. (
А те примеры конечно да, из серии вредных советов.
А вот и настоящий вопрос для собеседования:
public synchronized int getCount() {
return count;
}
Чем такая сигнатура отличается от public int getCount()
с точки зрения вызывающего кода?
И это, computeIfAbsent
блокирует чтение. Так что вся третья часть — булшит.
3 вопроса на собеседование о многопоточности в Java