Java线程死锁

Java线程死锁


死锁是一种特定的程序状态,在实体之间,由于循环依赖导致彼此一直处于等待之中,没有任何个体可以继续前进。死锁不仅仅是在线程之间会发生,存在资源独占的进程之间同样也 可能出现死锁。通常来说,我们大多是聚焦在多线程场景中的死锁,指两个或多个线程之 间,由于互相持有对方需要的锁,而永久处于阻塞的状态。

Java线程死锁是一个经典的多线程问题,因为不同的线程都在等待那些根本不可能被释放的锁,从而导致所有的工作都无法完成。如图所示

图片说明


如何去定位Java线程死锁呢?

定位死锁最常见的方式就是利用 jstack 等工具获取线程栈,然后定位互相之间的依赖关系,进而找到死锁。如果是比较明显的死锁,往往 jstack 等就能直接定位,类似 JConsole 甚至可以在图形界面进行有限的死锁检测。
既然了解了用什么工具去定位线程死锁,那我们模拟一个Java线程死锁的情况,实战定位线程死锁
死锁代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
* @Author:luomo
* @CreateTime: 2020/3/28
* @Description:模拟DeadLock
*/
public class deadLock implements Runnable{
public static Object obj1=new Object();
public static Object obj2=new Object();
private int flag;
deadLock(int flag){
this.flag=flag;
}

@Override
public void run() {
if(flag==0){
synchronized (obj1){
System.out.println(Thread.currentThread().getName()+"成功获取锁1");
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"尝试获取锁2");
synchronized (obj2){
System.out.println(Thread.currentThread().getName()+"成功获取锁2");


}
}
}else{
synchronized (obj2){
System.out.println(Thread.currentThread().getName()+"成功获取锁2");
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"尝试获取锁1");
synchronized (obj1){
System.out.println(Thread.currentThread().getName()+"成功获取锁2");


}
}
}

}

public static void main(String[] args) {
deadLock d1=new deadLock(0);
deadLock d2=new deadLock(1);
Thread thread1=new Thread(d1);
Thread thread2=new Thread(d2);
thread1.start();
thread2.start();

}

}

代码运行:

从运行结果我们看到Thread1和Thread0同时都在争用对方已经占有的锁,进而产生死锁。


如何定位死锁

如果程序发生了死锁,我们如何去定位死锁?我们可以通过JConsole工具来发现死锁。
打开cmd:输入 JConsole 回车
我们可以看到一个可视化的工具,找到死锁进程点击连接

图片说明

我们可以看到有检查死锁的选项

图片说明

图片说明

图片说明

通过上图我们可以发现产生死锁的线程,从而定位到发生死锁的代码。

当然我们还可以使用Jstack + pid的方式来定位问题

图片说明

文章目录
  1. 1. Java线程死锁
    1. 1.1. 如何去定位Java线程死锁呢?
    2. 1.2. 如何定位死锁
,