美文网首页Java
使用JDK自带的工具jstack找出造成运行程序死锁的原因

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

作者: 华山令狐冲 | 来源:发表于2018-08-22 12:15 被阅读14次

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的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:


相关文章

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

    Java多线程编程也是Java面试中经常考察的内容。刚接触Java多线程编程的朋友们,可能会不慎写出一些会导致死锁...

  • jvm监控

    jdk自带工具 jps jmap jhat jstat jstack 可解决的问题 内存不足,线程死锁,锁竞争,线...

  • 死锁排查

    java 自带了工具 bin目录下 1、使用jps定位进程号 命令 jps -l 2、使用jstack查看死锁问题

  • jvm 性能调优工具之 jstack

    概述 jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 Java 应用程序中线程堆栈信息。 J...

  • jvm 性能调优工具之 jstack

    概述 jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 Java 应用程序中线程堆栈信息。 J...

  • Thread死锁问题

    线程死锁 当线程发生死锁的情况时,用eclipse很难找出真正的原因所在。需要借住jdk自带的“java Visu...

  • JVM常用命令之-----jstack

    Jstack jstack命令主要用于调试java程序运行过程中的线程堆栈信息,可以用于检测死锁,进程耗用cpu过...

  • 6 款 Java 8 自带工具,轻松分析定位 JVM 问题!

    这篇文章中介绍下如何使用 JDK 自带工具来分析和定位 Java 程序的问题。 使用 JDK 自带工具查看 JVM...

  • jstack实战死循环与死锁

    jstack可以打印jvm内所有的线程,利用jstack可以排除程序运行时出现的死循环或者死锁问题。 1、实战死循...

  • 死锁定位

    运行可以产生死锁的程序 在cmd中输入jdk自带的 jps -l命令(类似于linux中的ps -ef|grep ...

网友评论

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

    本文链接:https://www.haomeiwen.com/subject/boweiftx.html