Что такое дедлок
Что проверяют
Понимаете ли вы причину взаимной блокировки, а не только её описание. Сильный ответ отличается тем, что даёт правило проектирования и способ диагностики, а не пересказ примера с двумя потоками.
Как отвечать
Определение: два или больше потоков встали навсегда, потому что каждый держит ресурс, нужный другому, и ждёт освобождения встречного.
Назовите четыре условия, которые должны совпасть одновременно: взаимное исключение, удержание с ожиданием, невозможность отобрать ресурс и кольцо в графе ожидания. Снимите любое из них, и дедлок невозможен. Это и есть каркас ответа, дальше идут приёмы.
Что делают на практике:
- глобальный порядок захвата: если все берут блокировки в одном и том же порядке, кольцо не замыкается. Порядок задают по устойчивому признаку, например по идентификатору объекта;
- сужение области: один замок вместо двух, атомарные типы и готовые потокобезопасные коллекции вместо ручной синхронизации;
tryLockс таймаутом уReentrantLock: поток, не получивший второй замок, отпускает первый и пробует снова. Уsynchronizedтаймаута нет вовсе, и это главная причина переходить на явные блокировки;- никаких вызовов чужого кода под удерживаемой блокировкой: колбэк захватит свой замок и замкнёт кольцо.
Про диагностику: дамп потоков сообщает о найденной взаимной блокировке явно, а из кода её видно через ThreadMXBean.
Где спотыкаются
Думают, что виртуальная машина разрулит ситуацию сама. Она умеет только сообщить о ней в дампе: безопасно снять поток нельзя, автоматического восстановления нет, лечится перезапуском. База данных ведёт себя иначе, она выбирает жертву и откатывает её транзакцию.
Смешивают дедлок с соседними состояниями. Живая блокировка это когда потоки не стоят, а бесконечно уступают друг другу, голодание это когда поток не получает ресурс из-за приоритетов. Симптом похож, причина и лечение разные.
Прячут проблему таймаутом и повтором, не меняя порядок захвата. Под нагрузкой такой код начинает крутить попытки по кругу, тратит процессорное время и всё равно падает по истечении ожидания в самый неудобный момент.