什么情况下才会出现死锁呢?一种比较典型的情况是:
有两个线程,就叫做thread1 和thread2,这两个线程的执行过程中都需要获取资源A和资源B的锁。当出现这种情况的时候,就会导致两个线程死锁:
Thread1访问A资源,然后准备访问B资源,Thread2先访问B资源,然后准备访问A资源。当thread1和thread2同时执行的时候,就可能导致死锁。因为可能thread1一直没法获取到资源B的锁,而Thread2也一直没法获取到资源A的锁,就都卡在那里,等待着获取一个永远获取不到的锁。
我们可以手写一段会产生死锁的代码:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class DeadLockTest {
// private Object A = new Object();
// private Object B = new Object();
public static void main(String[] args) {
Lock A = new ReentrantLock();
Lock B = new ReentrantLock();
new Thread(){
public void run(){
System.out.println("Thread1 -- trying to get lock A");
A.lock();
System.out.println("Thread1 -- get lock A successfully!");
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread1 -- trying to get lock B");
B.lock();
System.out.println("Thread1 -- get lock B successfully!");
}
}.start();
new Thread(){
public void run(){
System.out.println("Thread2 -- trying to get lock B");
B.lock();
System.out.println("Thread2 -- get lock A successfully!");
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread2 -- trying to get lock A");
A.lock();
System.out.println("Thread2 -- get lock B successfully!");
}
}.start();
}
}
上面的逻辑很简单,就是thread1和thread2都分别希望能够得到A的锁和B的锁。但是有点不同的是thread1先获得A锁,然后接下来准备获得B锁。thread2希望做到同样的事情,但是获取锁的顺序是相反的,准备先获得B锁,然后获得A锁。
为了确保死锁一定会发生,我让每个线程在获得第一个锁之后,暂停半秒。果然最终结果和预想的一样,结果如下:
Thread1 – trying to get lock A
Thread1 – get lock A successfully!
Thread2 – trying to get lock B
Thread2 – get lock A successfully!
Thread1 – trying to get lock B
Thread2 – trying to get lock A
最后thread1和thread2都卡在了获取第二个锁的地方,因为A锁和B锁此刻都已经被获取,没有被释放,所以此刻是没法获取到锁资源的。