Deadlock — это ситуация в многопоточном программировании, когда два или более потоков бесконечно блокируют друг друга, ожидая освобождения ресурсов, которые они удерживают. Это приводит к полной остановке выполнения программы.
Для возникновения взаимной блокировки необходимо одновременное выполнение четырех условий (условия Коффмана):
public class DeadlockExample {
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
synchronized (lock1) {
System.out.println("Thread 1: Удерживает lock1");
try { Thread.sleep(100); } catch (InterruptedException e) {}
synchronized (lock2) {
System.out.println("Thread 1: Удерживает lock1 и lock2");
}
}
});
Thread thread2 = new Thread(() -> {
synchronized (lock2) {
System.out.println("Thread 2: Удерживает lock2");
try { Thread.sleep(100); } catch (InterruptedException e) {}
synchronized (lock1) {
System.out.println("Thread 2: Удерживает lock2 и lock1");
}
}
});
thread1.start();
thread2.start();
}
}
В этом примере:
lock1
и ждет lock2
lock2
и ждет lock1
jstack <pid>
// Правильный подход:
synchronized(lock1) {
synchronized(lock2) {
// код
}
}
tryLock()
с таймаутом
if (lock1.tryLock(100, TimeUnit.MILLISECONDS)) {
try {
if (lock2.tryLock(100, TimeUnit.MILLISECONDS)) {
// код
}
} finally {
lock1.unlock();
}
}
java.util.concurrent.atomic
В Android deadlock особенно опасен, так как может привести к ANR (Application Not Responding). Типичные сценарии:
Deadlock — серьезная проблема многопоточности, возникающая при циклическом ожидании ресурсов. Для предотвращения необходимо соблюдать порядок блокировок, использовать таймауты и атомарные операции, а также тщательно проектировать архитектуру приложения.