看此文章前请先了解之前一篇文章 "Java死锁之理解死锁" 中的死锁示例
java 中提供了可以检测死锁的工具类ThreadMXBean,我们可以用它来在项目运行时期使用代码去检测是否有死锁存在.
下面这段代码请参考"理解java线程死锁"这篇文章,我们在其中添加了使用ThreadMXBean获取死锁信息的代码
public class TestThread {
public static final Object lock1 = new Object();//锁对象1
public static final Object lock2 = new Object();//锁对象2
//获取ThreadMXBean
public static ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
//测试方法
public static void main(String[] args) throws InterruptedException {
//启动死锁线程
new A("A").start();
new B("B").start();
//等待一段时间再执行死锁检测
Thread.sleep(200);
//获取到所有死锁线程的id
long[] deadlockedThreads = mbean.findDeadlockedThreads();
//遍历数组获取所有的死锁线程详细堆栈信息并打印
for (long pid : deadlockedThreads) {
//此方法获取不带有堆栈跟踪信息的线程数据
//hreadInfo threadInfo = mbean.getThreadInfo(pid);
//第二个参数指定转储多少项堆栈跟踪信息,设置为Integer.MAX_VALUE可以转储所有的堆栈跟踪信息
ThreadInfo threadInfo = mbean.getThreadInfo(pid,Integer.MAX_VALUE);
System.out.println(threadInfo);
}
}
}
打印出的死锁线程信息如下: 其中 "B" , "A" 是我的死锁示例中两个线程的名字
"B" Id=14 BLOCKED on java.lang.Object@58d25a40 owned by "A" Id=13
at test.B.run(TestThread.java:70)
- blocked on java.lang.Object@58d25a40
"A" Id=13 BLOCKED on java.lang.Object@726f3b58 owned by "B" Id=14
at test.A.run(TestThread.java:47)
- blocked on java.lang.Object@726f3b58
PS:检测死锁和获取堆栈信息是比较费性能的操作,如非必要不要经常执行