一丶什么是死锁?
死锁就是当两个或两个以上的线程因竞争相同资源而处于无限期的等待,这样就导致了多个线程的阻塞,出现程序无法正常运行和终止的情况,如下图,线程A已经持有了锁1,但它还想要得锁2才会释放自己的锁1,而线程B已经有了锁2,但它也是想要得到线程A的锁1才会释放的锁2,这样就会无限阻塞导致死锁了。
以下一个例子来模拟死锁。
//创建两个对象
Object a = new Object();
Object b = new Object();
//创建两个线程模拟死锁
//A线程
new Thread(() -> {
synchronized(a){
System.out.println("持有锁a, 还想继续获取锁b");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (b){
System.out.println("持有锁a, 获取成功锁b");
}
}
}, "A").start();
//B线程
new Thread(() -> {
synchronized(b){
System.out.println("持有锁b, 还想继续获取锁a");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (a){
System.out.println("持有锁b, 获取成功锁a");
}
}
}, "B").start();
控制台输出:
持有锁a, 获取锁b
持有锁b, 获取锁a
可见线程a和线程b都没有拿到自己下一个想要得锁(也就是对方的锁),这就是典型的死锁。
二丶windows可以通过dos命令也可以查看死锁情况:
1. 输入命令: jps -l 查看进程,类似Linux的ps -ef
2. 找到自己的程序进程编号,并输入命令: jstack 11572 (我当前这个死锁l例子程序是11572),可以看到显示找到了一个死锁.。