zoukankan      html  css  js  c++  java
  • 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();
        }
    }
    复制代码
  • 相关阅读:
    Bresenham画线算法
    DDA算法
    GL_LINES & GL_LINE_STRIP & GL_LINE_LOOP
    贝塞尔曲线
    弱引用
    Lambert模型
    ShadowVolume
    Phong Shading
    求反射向量
    Vertex Modifier of Surface Shader
  • 原文地址:https://www.cnblogs.com/lianghe01/p/8227860.html
Copyright © 2011-2022 走看看