14-定位死锁

nobility 发布于 2021-05-27 433 次阅读


定位死锁

jstack

使用JDK自带命令jstack 进程号对某个Java进程的线程栈进行分析(使用jps命令可查看Java程序的pid),若发现死锁会打印以下信息:对于不明显的死锁可能无法检测出来

Found one Java-level deadlock:
=============================
"Thread-0":
  waiting to lock monitor 0x0000023e7f4e8680 (object 0x0000000089cea620, a java.lang.Object),
  which is held by "Thread-1"
"Thread-1":
  waiting to lock monitor 0x0000023e7ea06f00 (object 0x0000000089cea610, a java.lang.Object),
  which is held by "Thread-0"

Java stack information for the threads listed above:
===================================================
"Thread-0":
        at Main.lambda$main$0(Main.java:17)
        - waiting to lock <0x0000000089cea620> (a java.lang.Object)
        - locked <0x0000000089cea610> (a java.lang.Object)
        at Main$$Lambda$14/0x0000000100066840.run(Unknown Source)
        at java.lang.Thread.run(java.base@11.0.8/Thread.java:834)
"Thread-1":
        at Main.lambda$main$1(Main.java:30)
        - waiting to lock <0x0000000089cea610> (a java.lang.Object)
        - locked <0x0000000089cea620> (a java.lang.Object)
        at Main$$Lambda$15/0x0000000100066c40.run(Unknown Source)
        at java.lang.Thread.run(java.base@11.0.8/Thread.java:834)

Found 1 deadlock.

ThreadMXBean

ThreadMXBean是Java中提供的一个检测死锁情况的工具类

public static void threadMXBean(int timeInterval) {  //每timeInterval时间进行一次死锁检测
  new Thread(() -> {  //新开启一个死锁检测的线程
    ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();  //获取ThreadMXBean实例
    long[] deadlockedThreads = null;
    while (true) {
      try {
        Thread.sleep(timeInterval);  //每timeInterval时间进行一次死锁检测
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      deadlockedThreads = threadMXBean.findDeadlockedThreads();  //查看当前JVM中是否有死锁发生
      if (deadlockedThreads != null && deadlockedThreads.length > 0) {  //返回不为null且数组有内容(线程ID)则发生死锁
        for (int i = 0; i < deadlockedThreads.length; i++) {
          long deadlockedThread = deadlockedThreads[i]; //获取线程id
          ThreadInfo threadInfo = threadMXBean.getThreadInfo(deadlockedThread);  //使用线程ID获取线程西悉尼
          System.out.println("发现死锁线程" + threadInfo.getThreadName() + ",正在进行处理...");  //进行处理
        }
        System.exit(0);  //处理结束后退出程序
      }
    }
  }).start();
}
此作者没有提供个人介绍
最后更新于 2021-05-27