Ответ
Deadlock (взаимная блокировка) — это ситуация в многопоточном программировании, когда два или более потока бесконечно ожидают друг друга, освобождения заблокированных ими ресурсов (мониторов объектов).
Классический пример из жизни: Два человека (Поток A и Поток B) стоят в дверном проеме. Каждый ждет, пока другой отступит, чтобы пройти первым. Никто не двигается — возникает тупик.
Технический пример на Java:
public class DeadlockExample {
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
public static void main(String[] args) {
Thread threadA = new Thread(() -> {
synchronized (lock1) { // 1. threadA захватывает lock1
System.out.println("Thread A: Holding lock 1...");
try { Thread.sleep(100); } catch (InterruptedException e) {}
System.out.println("Thread A: Waiting for lock 2...");
synchronized (lock2) { // 3. threadA пытается захватить lock2, но он у threadB
System.out.println("Thread A: Acquired both locks!");
}
}
});
Thread threadB = new Thread(() -> {
synchronized (lock2) { // 2. threadB захватывает lock2
System.out.println("Thread B: Holding lock 2...");
try { Thread.sleep(100); } catch (InterruptedException e) {}
System.out.println("Thread B: Waiting for lock 1...");
synchronized (lock1) { // 4. threadB пытается захватить lock1, но он у threadA
System.out.println("Thread B: Acquired both locks!");
}
}
});
threadA.start();
threadB.start(); // Программа зависнет в deadlock
}
}
Условия возникновения deadlock (Условия Коффмана):
- Взаимное исключение: Ресурс не может быть использован более чем одним потоком одновременно.
- Удержание и ожидание: Поток, удерживая один ресурс, ждет другой.
- Отсутствие вытеснения: Ресурс нельзя отнять у потока, только добровольно освободить.
- Циклическое ожидание: Возникает круг потоков, каждый из которых ждет ресурс, удерживаемый следующим в цепи.
Профилактика: Упорядочивание захвата блокировок, использование tryLock() с таймаутом, избегание вложенных синхронизаций.