Выбор ответа Senior java.util.concurrent и виртуальные потоки обновлено
Рекурсия в computeIfAbsent
Вопрос
Функция внутри concurrentHashMap.computeIfAbsent(k, ...) сама вызывает computeIfAbsent на той же карте для другого ключа. Чем это опасно?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Функция работает под блокировкой корзины: возможен Recursive update. ConcurrentHashMap выполняет функцию отображения, удерживая блокировку на корзине.
Варианты ответа
- Ничем:
computeIfAbsentреентерабелен и умеет вложенные вызовы - Второй вызов всегда вернёт null, пока не закончится первый
- Функция работает под блокировкой корзины: возможен
Recursive updateправильный ответ - Карта будет скопирована целиком на время вложенного вычисления
Разбор
ConcurrentHashMap выполняет функцию отображения, удерживая блокировку на корзине. Документация требует, чтобы функция была короткой и не изменяла карту. Рекурсивное обновление той же корзины обнаруживается и даёт IllegalStateException: Recursive update, а в старых версиях Java 8 мог случиться вечный цикл (livelock). Тяжёлые вычисления и обращения к самой карте внутри функции не делают.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «java.util.concurrent и виртуальные потоки»
- Что выведет: цепочка CompletableFuture
- В каком потоке выполнится thenApply
- CompletableFuture без executor
- Опасность newFixedThreadPool
- CountDownLatch и CyclicBarrier
- Устройство ConcurrentHashMap
- ReentrantLock и synchronized
- Виртуальные потоки