写点什么

使用 JDK 自带的工具 jstack 找出造成运行程序死锁的原因

作者:Jerry Wang
  • 2021 年 12 月 18 日
  • 本文字数:1200 字

    阅读完需:约 4 分钟

使用JDK自带的工具jstack找出造成运行程序死锁的原因

Java 多线程编程也是 Java 面试中经常考察的内容。刚接触 Java 多线程编程的朋友们,可能会不慎写出一些会导致死锁(deadlock)的应用出来。如何分析造成 Java 多线程的原因呢?很多时候我们在怀疑造成死锁的语句设置断点,单步调试,反而又不能重现了。这种现象很正常,因为咱们单步调试和直接运行程序,代码执行的时序是不同的,很可能无法满足死锁的触发条件。



实际上,JDK 已经给 Java 程序员提供了强大的死锁分析工具,能够直接分析一个正在运行的并且处于死锁状态的应用,并给出具体是哪一行 Java 代码引起的死锁。


这篇文章就以一个例子来给大家演示如何使用这个 JDK 提供的标准工具。


这个工具叫 jstack,就是 JDK 安装目录的 bin 文件夹下的一个执行文件。


我们首先写一个会导致死锁的应用出来。


public class DeadLockExample {  public static void main(String[] args) {    final String resource1 = "ABAP";    final String resource2 = "Java";    Thread t1 = new Thread() {      public void run() {        synchronized (resource1) {          System.out.println("Thread 1: locked resource 1");          try {            Thread.sleep(100);          }          catch (Exception e) {          }          synchronized (resource2) {            System.out.println("Thread 1: locked resource 2");          }        }      }    }    ;    Thread t2 = new Thread() {      public void run() {        synchronized (resource2) {          System.out.println("Thread 2: locked resource 2");          try {            Thread.sleep(100);          }          catch (Exception e) {          }          synchronized (resource1) {            System.out.println("Thread 2: locked resource 1");          }        }      }    }    ;    t1.start();    t2.start();  }}
复制代码


这个应用思路很简单,同时启动两个线程,分别锁住了 resource1 和 resource2,然后休眠 0.1 秒,接着分别尝试去请求资源 resource2 和 resource1。


执行应用,在控制台打印出下列输出后,进入死锁状态:


Thread 1: locked resource 1


Thread 2: locked resource 2


使用命令行 jps -l -m 找到处于死锁状态应用的进程 id。从下图得知死锁进程为 51476:



然后使用命令行 jstack 51476 打印这个进程的运行栈信息。



我上图红色高亮出的 0x00000000d6f64988 和 0x00000000d6f649b8 代表了代码中的两个资源“ABAP” 和“Java”。


jstack 打印的输出非常清晰,显示了具体哪行 Java 代码试图去锁定哪一个 Java 资源(下图的 waiting to lock)但是没有成功, 并且将失败的原因,即拥有当前请求资源的线程名称也打印了出来。



有了 jstack,Java 程序员不用对着冗长烧脑的多线程代码去冥思苦想了,JDK 会自动把死锁原因打印出来,太方便了。


要获取更多 Jerry 的原创技术文章,请关注公众号"汪子熙"。

发布于: 2 小时前阅读数: 4
用户头像

Jerry Wang

关注

个人微信公众号:汪子熙 2017.12.03 加入

SAP成都研究院开发专家,SAP社区导师,SAP中国技术大使。

评论

发布
暂无评论
使用JDK自带的工具jstack找出造成运行程序死锁的原因