ENIGMA AI
ENIGMA AI

Что такое дедлок?

встречается 4× junior concurrency

Как ответить

Дедлок (взаимная блокировка) — ситуация, когда два или больше потоков (или процессов) навсегда застревают в ожидании ресурсов, которые удерживают друг друга. Каждый поток ждёт, пока другой освободит нужный ему ресурс, и никто не может продолжить работу.

Для возникновения дедлока должны одновременно выполняться четыре условия (их часто называют условиями Коффмана):

  • Взаимное исключение — ресурс может быть захвачен только одним потоком за раз.
  • Удержание и ожидание — поток удерживает уже захваченный ресурс и при этом ожидает захвата другого.
  • Отсутствие вытеснения — ресурс нельзя принудительно отобрать у потока; освободить его может только сам поток.
  • Циклическое ожидание — существует замкнутая цепочка потоков, каждый из которых ждёт ресурс, удерживаемый следующим потоком в цепочке.

Самый простой пример — два потока с двумя блокировками:

// Поток 1
synchronized (lockA) {
    synchronized (lockB) {
        // работа
    }
}

// Поток 2
synchronized (lockB) {
    synchronized (lockA) {
        // работа
    }
}

Если оба потока стартуют одновременно, может возникнуть дедлок: первый захватит lockA и ждёт lockB, второй захватил lockB и ждёт lockA.

Основные способы предотвратить дедлок:

  • Фиксированный порядок захвата блокировок — все потоки всегда захватывают блокировки в одинаковой последовательности (например, сначала lockA, потом lockB).
  • Таймауты при попытке захвата — использовать tryLock с указанием времени ожидания. Если не удалось захватить все блокировки, поток освобождает уже захваченные и повторяет попытку.
  • Минимизация области блокировки — блокировать только критические секции, а не большие участки кода.
  • Использование lock-free структур (атомарные классы, ConcurrentHashMap) — когда можно обойтись без явных блокировок.

На практике дедлоки чаще всего возникают из‑за невнимательности при работе с вложенными блокировками или при использовании callback-ов/слушателей. Инструменты вроде jstack, VisualVM или ThreadMXBean в Java позволяют дампить потоки и видеть циклические ожидания.

Ключевые тезисы

  • Дедлок — взаимная блокировка, когда каждый поток ждёт ресурс, захваченный другим, и ни один не может двигаться дальше.
  • Тривиальный пример: два потока захватывают два мьютекса в разном порядке.
  • Для дедлока нужны четыре условия: взаимное исключение, удержание и ожидание, отсутствие вытеснения, циклическое ожидание.
  • Основные методы предотвращения: единый порядок захвата блокировок, tryLock с таймаутом, минимизация критических секций.
  • Обнаружить дедлок можно с помощью дампа потоков (jstack, VisualVM) — там будут видны ожидания и зацикленные зависимости.

Что спросят дальше

  • — Как выявить дедлок в уже работающем приложении? Какие инструменты или методы используете?
  • — Что такое livelock и чем он отличается от deadlock? Приведите пример.
  • — Если бы вы проектировали систему с множеством блокировок, какие правила заложили бы, чтобы исключить взаимные блокировки?

Готовьтесь к собеседованию с ENIGMA AI

AI-суфлёр подсказывает ответы прямо на собеседовании в реальном времени — незаметно для интервьюера.

Скачать приложение