Jstack发现多线程死锁

在多线程的使用中,有时会碰到死锁,死锁会造成应用程序阻塞,浪费系统资源。下面探讨如何发现和解决死锁:

产生死锁

首先先写一段能够产生死锁的代码:

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
private static Object lock1=new Object();
private static Object lock2=new Object();
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
synchronized (lock1){
System.out.println("线程1获得 lock1");
SleepUtils.Sleep(1);
synchronized (lock2){
System.out.println("线程1获得 lock2");
}
}
System.out.println("线程1结束 ");
}
}.start();
new Thread() {
@Override
public void run() {
synchronized (lock2){
System.out.println("线程2获得 lock2");
SleepUtils.Sleep(1);
synchronized (lock1){
System.out.println("线程2获得 lock1");
}
}
System.out.println("线程2结束 ");
}
}.start();
}

运行上面的结果,线程会各自阻塞在同步锁的那个地方,产生了死锁,运行结果如下:

1
2
线程1获得 lock1
线程2获得 lock2

我们使用jps命令, 查询Java的线程,如下:

jps

使用jstack 16071命令查看堆栈信息

jps

从上面可以看出来,两个线程都在等待一个内存地址,这个就是我们的死锁