Deadlock - причины, симптомы и способы устранения
Deadlock (затруднение) — это состояние, когда два или более потока заблокированы, ожидая ресурс, занятый другим потоком.
Пример кода, который может привести к deadlock:
java
public class DeadlockExample {
public static void main(String[] args) {
Object resource1 = new Object();
Object resource2 = new Object();
Thread thread1 = new Thread(() -> {
synchronized (resource1) {
System.out.println("Thread 1 acquired resource 1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1 waiting to acquire resource 2");
synchronized (resource2) {
System.out.println("Thread 1 acquired resource 2");
}
}
});
Thread thread2 = new Thread(() -> {
synchronized (resource2) {
System.out.println("Thread 2 acquired resource 2");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 2 waiting to acquire resource 1");
synchronized (resource1) {
System.out.println("Thread 2 acquired resource 1");
}
}
});
thread1.start();
thread2.start();
}
}
В этом примере есть два потока, которые используют два различных ресурса. Thread 1 блокирует resource1 и ожидает разблокировки resource2, который занят Thread 2. Thread 2, в свою очередь, блокирует resource2 и ожидает разблокировки resource1. Как результат, оба потока заблокированны, ожидая разблокировки друг друга, что приводит к deadlock.
Чтобы избежать deadlock, необходимо следовать ряду правил в многопоточном программировании. Например:
1. Избегайте блокировок вложенных мониторов (nested monitors).
2. При использовании нескольких ресурсов блокируйте их в одном порядке для всех потоков.
3. Используйте больше неблокирующих алгоритмов.
4. Разблокируйте ресурсы как можно скорее, когда они вам больше не нужны.
5. Используйте методы tryLock() и tryLock(long timeout, TimeUnit unit), чтобы избежать блокировок.
Общая стратегия заключается в том, чтобы убедиться, что мониторы блокируются в правильном порядке и разблокируются, как только они становятся ненужными. Также необходимо избегать перехода от одной блокировки к другой, поскольку это может привести к deadlock.