Java死锁条件
死锁是指两个或多个线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉,它们都将无法继续执行下去。这种情况在多线程并发执行的环境中经常出现。
死锁的四个必要条件:
互斥条件:一个资源每次只能被一个线程使用。
请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放。
不剥夺条件:线程已获得的资源,在未使用完之前,不能被其他线程强行剥夺。
循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。
只有满足以上所有条件,才会发生死锁。而只要破坏其中一个条件,就能避免死锁。
一个简单的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 thread1 = new Thread(() -> {
synchronized (Lock1) {
System.out.println("Thread 1: Holding lock 1...");
try { Thread.sleep(100); } catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Acquired lock 2!");
}
}
});
Thread thread2 = new Thread(() -> {
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 2...");
try { Thread.sleep(100); } catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 1...");
synchronized (Lock1) {
System.out.println("Thread 2: Acquired lock 1!");
}
}
});
thread1.start();
thread2.start();
}
}
在这个示例中,thread1
尝试获取Lock1
,然后尝试获取Lock2
;同时thread2
尝试获取Lock2
,然后尝试获取Lock1
。由于两个线程之间存在循环等待,它们都被阻塞,并且都不能继续执行,导致死锁。
要避免这种死锁,一种简单的方法是总是按固定的顺序请求锁,例如总是先请求Lock1
,然后再请求Lock2
。