Java线程死锁查看分析方法

Posted sxhong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java线程死锁查看分析方法相关的知识,希望对你有一定的参考价值。

如何查看是否有Java线程死锁?下面介绍两种方法。

一.Jconsole
        Jconsole是JDK自带的图形化界面工具,使用JDK给我们的的工具JConsole,可以通过打开cmd然后输入jconsole打开。


        连接到需要查看的进程。

        打开线程选项卡,然后点击左下角的“检测死锁” 。


        jconsole就会给我们检测出该线程中造成死锁的线程,点击选中即可查看详情:


从上图中我们可以看出:

        在线程Thread-1中,从状态可以看出,它想申请java.lang.Object@35b4e829这个资源,但是这个资源已经被Thread-0拥有了,所以就堵塞了。

        在线程Thread-0中,从状态可以看出,它想申请java.lang.Object@2db8dc9这个资源,但是这个资源已经被Thread-1拥有了,所以就堵塞了。

        Thread-1一直等待java.lang.Object@35b4e829资源,而Thread–0一直等待java.lang.Object@2db8dc9资源,于是这两个线程就这么僵持了下去,造成了死锁。

 

二.Jstack

        Jstack是JDK自带的命令行工具,主要用于线程Dump分析。

        1.我们先用Jps来查看java进程id(或者Linux的ps命令)


        2.看一下jstack的使用

        3.jstack输出线程dump信息到文件

        用比较工程查看带-l和不带-l的区别如下:


        4.查看dump文件,然后进行分析

        其中有一行是at DeadThread.run(DeadThread.java:37),说明Thread-1实在DeadThread类的37行处发生死锁,其中at DeadThread.run(DeadThread.java:21),说明Thread-0是在DeadThread类的21行处发生死锁。详细的jstack dump文件分析请参看:http://www.cnblogs.com/flyingeagle/articles/6853454.html

        从而定位到死锁发生的原因,及具体位置:Thread-0获得了锁lock1,接下来期望获得锁lock2,(第20行),但是此时Thread-1获得了锁lock2,接下来期望获得锁lock2,(第37行),因而发生了死锁。

 

附实例DeadThread.java代码:

public class DeadThread implements Runnable 

    public String username;
    public Object lock1 = new Object();
    public Object lock2 = new Object();

    @Override
    public void run() 
        // TODO Auto-generated method stub  
        if (username.equals("a")) 
            synchronized (lock1) 
                try 
                    System.out.println("username = " + username);
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(3000);
                 catch (Exception e) 
                    // TODO: handle exception  
                    e.printStackTrace();
                
                synchronized (lock2) 
                    System.out.println("按lock1->lock2的顺序执行代码");
                
            
        
        if (username.equals("b")) 
            synchronized (lock2) 
                try 
                    System.out.println("username = " + username);
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(3000);

                 catch (Exception e) 
                    // TODO: handle exception  
                    e.printStackTrace();
                
                synchronized (lock1) 
                    System.out.println("按lock2->lock1顺序执行代码");
                
            

        
    

    public void setFlag(String username) 
        this.username = username;
    
    
    public static void main(String[] args) 

        DeadThread dt1 = new DeadThread();
        dt1.setFlag("a");
        Thread t1 = new Thread(dt1);
        t1.start();

        try 
            Thread.sleep(2000);
         catch (InterruptedException e) 
            e.printStackTrace();
        

        dt1.setFlag("b");
        Thread t2 = new Thread(dt1);

        t2.start();
    

 

文章来源:http://blog.csdn.net/abc86319253/article/details/49534225

以上是关于Java线程死锁查看分析方法的主要内容,如果未能解决你的问题,请参考以下文章

使用Windbg分析多线程临界区死锁问题分享

使用Windbg分析多线程临界区死锁问题分享

mysql 死锁排查

JAVA死锁排查-性能测试问题排查思路

Java多线程:死锁

Java多线程:并发死锁问题分析资源限制的挑战