Выбор ответа Senior java.util.concurrent и виртуальные потоки обновлено

Рекурсия в computeIfAbsent

Вопрос

Функция внутри concurrentHashMap.computeIfAbsent(k, ...) сама вызывает computeIfAbsent на той же карте для другого ключа. Чем это опасно?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Функция работает под блокировкой корзины: возможен Recursive update. ConcurrentHashMap выполняет функцию отображения, удерживая блокировку на корзине.

Варианты ответа

  1. Ничем: computeIfAbsent реентерабелен и умеет вложенные вызовы
  2. Второй вызов всегда вернёт null, пока не закончится первый
  3. Функция работает под блокировкой корзины: возможен Recursive updateправильный ответ
  4. Карта будет скопирована целиком на время вложенного вычисления

Разбор

ConcurrentHashMap выполняет функцию отображения, удерживая блокировку на корзине. Документация требует, чтобы функция была короткой и не изменяла карту. Рекурсивное обновление той же корзины обнаруживается и даёт IllegalStateException: Recursive update, а в старых версиях Java 8 мог случиться вечный цикл (livelock). Тяжёлые вычисления и обращения к самой карте внутри функции не делают.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме