Java中当我们的开发涉及到多线程的时候很容易遇到死锁问题,这篇文章主要解决遇到死锁问题如何定位。
1、Java中jdk 给我们提供了很便利的工具,帮助我们定位和分析死锁问题:
死锁产生原因:当两个或者多个线程互相持有一定资源,并互相等待其他线程释放资源而形成的一种僵局,就是死锁。
构建一个死锁的场景:
类:
package com.courage.dead;
public class DeadLock extends Thread {
private Object money;// 钱
private Object water;// 水
public boolean flag;// 标记持有对象锁
public DeadLock() {
super();
}
public DeadLock(Object money, Object water) {
super();
this.money = money;
this.water = water;
}
public void run() {
if (flag) {// true时,持有“钱”的锁
synchronized (money) {
System.out.println("有钱,等水");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (water) {
System.out.println("有水,等钱");
}
}
} else {
synchronized (water) {
System.out.println("有水,等钱");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (money) {
System.out.println("有钱,等水");
}
}
}
}
}
测试类:
public class Test {
public static void main(String[] args) {
// 创建共享资源的对象
Object money = new Object();
Object water = new Object();
// 创建线程类对象
DeadLock d1 = new DeadLock(money, water);
DeadLock d2 = new DeadLock(money, water);
d1.flag = true;
d2.flag = false;
// 启动线程
d1.start();
d2.start();
}
}
可以看到运行时,一个线程持有“水”资源,希望使用“钱”资源,而另一个线程持有“钱”资源,希望使用“水”资源,然后就陷入了相互等待的僵局,这样就形成了死锁。
2、Jconsole查看死锁
进入java安装的位置,输入Jconsole,然后弹出界面(或者进入安装目录/java/jdk1.70_80/bin/,点击Jconsole.exe):
然后点击进入:
可以看出,造成死锁的原因是Thread-1在等待Thread-2,而Thread-2在等待Thread-1。
3、Jstack查看死锁:
同样,也是进入jdk安装目录的bin下面,输入jps,先查看我们要检测死锁的进程:
看到进程Test的进程号:128,然后执行:Jstack -l 128
死锁信息: