Deadlock

Deadlock — цикл ожидания: каждый участник удерживает ресурс, нужный следующему, и никто не может продолжить.

// Поток A
synchronized (left) {
    synchronized (right) {
        move();
    }
}
 
// Поток B
synchronized (right) {
    synchronized (left) {
        move();
    }
}

Если A захватил left, а B — right, оба навсегда ждут второй монитор.

Условия возникновения

Классическая модель выделяет четыре одновременных условия:

  1. ресурс нельзя совместно использовать;
  2. поток удерживает один ресурс, ожидая другой;
  3. ресурс нельзя принудительно отобрать;
  4. существует цикл ожидания.

Устранение хотя бы одного условия разрушает deadlock.

Предотвращение

Единый порядок блокировок

Все операции захватывают сущности по стабильному ключу:

Account first = a.id() < b.id() ? a : b;
Account second = a.id() < b.id() ? b : a;
 
synchronized (first.lock()) {
    synchronized (second.lock()) {
        transfer(a, b, amount);
    }
}

Нужно отдельно обработать одинаковый ключ и перевод объекта самому себе.

Ограниченное ожидание

ReentrantLock.tryLock(timeout, unit) позволяет отказаться, освободить уже полученное и повторить с backoff. Это не доказывает отсутствие deadlock, но дает путь восстановления.

Уменьшение области lock

Не вызывать сеть, пользовательский callback или другой компонент под своей блокировкой. Если нужен согласованный снимок — скопировать состояние под lock, затем делать I/O вне него.

Диагностика

Thread dump показывает потоки, удерживаемые мониторы и waiting to lock. JVM часто прямо отмечает найденный Java-level deadlock. Нужно восстановить граф «поток → ожидаемый lock → владелец», а не ориентироваться только на BLOCKED.

На собеседовании

  • Что обязательно для deadlock? Циклическое ожидание при удержании ресурсов.
  • Самая практичная профилактика? Глобальный порядок захвата.
  • Поможет ли interrupt потоку у входа в synchronized? Нет, ожидание intrinsic monitor не interruptible.
  • Чем starvation отличается? Поток долго не получает ресурс, но система в целом движется.
  • Как подтвердить deadlock? Thread dump и граф владельцев/ожиданий.