怎么使用JDK的工具jstack找出运行时程序死锁的原因

  介绍

这篇文章给大家分享的是有关怎么使用JDK的工具jstack找出运行时程序死锁的原因的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。

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

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

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

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

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

公共类DeadLockExample {   公共静态void main (String [] args) {   最终字符串resource1=癆BAP";   最终字符串resource2=癑ava";   线程t1=新线程(){   公共空间run () {   同步(resource1) {   System.out.println(“线程1:锁定资源1“);   尝试{   thread . sleep (100);   }   捕获(异常e) {   }   同步(resource2) {   System.out.println(“线程1:锁定资源2“);   }   }   }   }   ;   线程t2=新线程(){   公共空间run () {   同步(resource2) {   System.out.println(“线程2:锁定资源2“);   尝试{   thread . sleep (100);   }   捕获(异常e) {   }   同步(resource1) {   System.out.println(“线程2:锁定资源1“);   }   }   }   }   ;   t1.start ();   t2.start ();   }   }

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

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

线程1:锁定资源1

线程2:锁定资源2

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

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

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

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

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

感谢各位的阅读!关于怎么使用JDK的工具jstack找出运行时程序死锁的原因就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到吧!

怎么使用JDK的工具jstack找出运行时程序死锁的原因