zoukankan      html  css  js  c++  java
  • Java死锁 Thread Dump分析

    Java中的死锁是指两个线程在互相等待对方释放锁的无限期阻塞现象。

    举个例子:

     1 public class TestDeadLock {
     2     public static void main(String[] args) {
     3         Dead1 d1 = new Dead1("Thread1");
     4         Dead2 d2 = new Dead2("Thread2");
     5         d1.setDead2(d2);
     6         d2.setDead1(d1);
     7         d1.start();
     8         d2.start();
     9     }
    10 }
    11 
    12 class Dead1 extends Thread {
    13     public Dead2 d2;
    14     public Dead1(String name) {
    15         super(name);
    16     }
    17     public void setDead2(Dead2 d2) {
    18         this.d2 = d2;
    19     }
    20     public void run() {
    21         test();
    22     }
    23     public synchronized void test() {
    24         try {
    25             Thread.sleep(500);
    26         } catch (InterruptedException e) {
    27             e.printStackTrace();
    28         }
    29         // 需要获取d2的锁,但是d2此时被另一个线程所拥有。
    30         d2.test();
    31     }
    32 }
    33 
    34 class Dead2 extends Thread {
    35     public Dead1 d1;
    36     public Dead2(String name) {
    37         super(name);
    38     }
    39     public void setDead1(Dead1 d1) {
    40         this.d1 = d1;
    41     }
    42     public void run() {
    43         test();
    44     }
    45     public synchronized void test() {
    46         try {
    47             Thread.sleep(500);
    48         } catch (InterruptedException e) {
    49             e.printStackTrace();
    50         }
    51         // 需要获取d1的锁,但是d1此时被另一个线程所拥有。
    52         d1.test();
    53     }
    54 }

    例子中,类Dead1和类Dead2分别继承Thread类,同时Dead1类里面定义了Dead2类型的变量,Dead2类里面定义了Dead1类型的变量,当在主线程里面分别创建它们的线程实例并分别调用set方法赋值。

    1。当线程Thread1(d1)启动时,它需要调用自己的test方法,而test方法里面需要调用Thread2(d2)的test方法,所以Thread1需要获得d2的锁,

    2。但是此时Thread2很可能已经进入了Dead2类的test方法,它已经获得了d2的锁,它正在等待线程1释放d1锁,而线程1又在等待线程2释放锁,

    3。于是,死锁产生了。程序永远不会结束。

      为了更好的证明死锁产生了,我们可以使用Java自带的VisualVM工具来查看Java Dump:

    由于我的系统是日文的,所以显示的是日语。

    再看详细的Thread Dump信息:

      1 2014-05-28 17:03:38
      2 Full thread dump Java HotSpot(TM) Client VM (23.7-b01 mixed mode):
      3 
      4 "RMI TCP Connection(4)-133.197.178.192" daemon prio=6 tid=0x00d6f800 nid=0x1060 runnable [0x18b6f000]
      5    java.lang.Thread.State: RUNNABLE
      6     at java.net.SocketInputStream.socketRead0(Native Method)
      7     at java.net.SocketInputStream.read(SocketInputStream.java:150)
      8     at java.net.SocketInputStream.read(SocketInputStream.java:121)
      9     at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
     10     at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
     11     - locked <0x090afdd0> (a java.io.BufferedInputStream)
     12     at java.io.FilterInputStream.read(FilterInputStream.java:83)
     13     at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
     14     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
     15     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
     16     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
     17     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
     18     at java.lang.Thread.run(Thread.java:722)
     19 
     20    Locked ownable synchronizers:
     21     - <0x090afed0> (a java.util.concurrent.ThreadPoolExecutor$Worker)
     22 
     23 "JMX server connection timeout 15" daemon prio=6 tid=0x185b9400 nid=0x18b4 in Object.wait() [0x18a0f000]
     24    java.lang.Thread.State: TIMED_WAITING (on object monitor)
     25     at java.lang.Object.wait(Native Method)
     26     - waiting on <0x09040bd0> (a [I)
     27     at com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:168)
     28     - locked <0x09040bd0> (a [I)
     29     at java.lang.Thread.run(Thread.java:722)
     30 
     31    Locked ownable synchronizers:
     32     - None
     33 
     34 "RMI Scheduler(0)" daemon prio=6 tid=0x185a8000 nid=0x1df8 waiting on condition [0x17e2f000]
     35    java.lang.Thread.State: TIMED_WAITING (parking)
     36     at sun.misc.Unsafe.park(Native Method)
     37     - parking to wait for  <0x08f71080> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
     38     at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
     39     at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
     40     at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1090)
     41     at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:807)
     42     at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
     43     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
     44     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
     45     at java.lang.Thread.run(Thread.java:722)
     46 
     47    Locked ownable synchronizers:
     48     - None
     49 
     50 "RMI TCP Accept-0" daemon prio=6 tid=0x00daf800 nid=0x5b8 runnable [0x1817f000]
     51    java.lang.Thread.State: RUNNABLE
     52     at java.net.DualStackPlainSocketImpl.accept0(Native Method)
     53     at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:121)
     54     at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
     55     at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:183)
     56     - locked <0x08fc4a18> (a java.net.SocksSocketImpl)
     57     at java.net.ServerSocket.implAccept(ServerSocket.java:522)
     58     at java.net.ServerSocket.accept(ServerSocket.java:490)
     59     at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:52)
     60     at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:387)
     61     at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:359)
     62     at java.lang.Thread.run(Thread.java:722)
     63 
     64    Locked ownable synchronizers:
     65     - None
     66 
     67 "DestroyJavaVM" prio=6 tid=0x005fb000 nid=0x19f4 waiting on condition [0x00000000]
     68    java.lang.Thread.State: RUNNABLE
     69 
     70    Locked ownable synchronizers:
     71     - None
     72 
     73 "Thread2" prio=6 tid=0x00c96c00 nid=0xdac waiting for monitor entry [0x17fbf000]
     74    java.lang.Thread.State: BLOCKED (on object monitor)
     75     at Dead1.test(TestDeadLock.java:25)
     76     - waiting to lock <0x08fc4b90> (a Dead1)
     77     at Dead2.test(TestDeadLock.java:52)
     78     - locked <0x08fc4b28> (a Dead2)
     79     at Dead2.run(TestDeadLock.java:43)
     80 
     81    Locked ownable synchronizers:
     82     - None
     83 
     84 "Thread1" prio=6 tid=0x00c94800 nid=0xb54 waiting for monitor entry [0x17ddf000]
     85    java.lang.Thread.State: BLOCKED (on object monitor)
     86     at Dead2.test(TestDeadLock.java:47)
     87     - waiting to lock <0x08fc4b28> (a Dead2)
     88     at Dead1.test(TestDeadLock.java:30)
     89     - locked <0x08fc4b90> (a Dead1)
     90     at Dead1.run(TestDeadLock.java:21)
     91 
     92    Locked ownable synchronizers:
     93     - None
     94 
     95 "Service Thread" daemon prio=6 tid=0x00c65000 nid=0x7c8 runnable [0x00000000]
     96    java.lang.Thread.State: RUNNABLE
     97 
     98    Locked ownable synchronizers:
     99     - None
    100 
    101 "C1 CompilerThread0" daemon prio=10 tid=0x00c58400 nid=0x193c waiting on condition [0x00000000]
    102    java.lang.Thread.State: RUNNABLE
    103 
    104    Locked ownable synchronizers:
    105     - None
    106 
    107 "Attach Listener" daemon prio=10 tid=0x00c53000 nid=0x110c waiting on condition [0x00000000]
    108    java.lang.Thread.State: RUNNABLE
    109 
    110    Locked ownable synchronizers:
    111     - None
    112 
    113 "Signal Dispatcher" daemon prio=10 tid=0x00c50000 nid=0x1900 runnable [0x00000000]
    114    java.lang.Thread.State: RUNNABLE
    115 
    116    Locked ownable synchronizers:
    117     - None
    118 
    119 "Finalizer" daemon prio=8 tid=0x00bdf400 nid=0x1c0c in Object.wait() [0x17ccf000]
    120    java.lang.Thread.State: WAITING (on object monitor)
    121     at java.lang.Object.wait(Native Method)
    122     - waiting on <0x08fc4e00> (a java.lang.ref.ReferenceQueue$Lock)
    123     at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
    124     - locked <0x08fc4e00> (a java.lang.ref.ReferenceQueue$Lock)
    125     at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
    126     at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)
    127 
    128    Locked ownable synchronizers:
    129     - None
    130 
    131 "Reference Handler" daemon prio=10 tid=0x00bda800 nid=0x1718 in Object.wait() [0x17c2f000]
    132    java.lang.Thread.State: WAITING (on object monitor)
    133     at java.lang.Object.wait(Native Method)
    134     - waiting on <0x08fc45d8> (a java.lang.ref.Reference$Lock)
    135     at java.lang.Object.wait(Object.java:503)
    136     at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
    137     - locked <0x08fc45d8> (a java.lang.ref.Reference$Lock)
    138 
    139    Locked ownable synchronizers:
    140     - None
    141 
    142 "VM Thread" prio=10 tid=0x00bd5400 nid=0x140c runnable 
    143 
    144 "VM Periodic Task Thread" prio=10 tid=0x00c76400 nid=0x1978 waiting on condition 
    145 
    146 JNI global references: 192
    147 
    148 
    149 Found one Java-level deadlock:
    150 =============================
    151 "Thread2":
    152   waiting to lock monitor 0x00bdf354 (object 0x08fc4b90, a Dead1),
    153   which is held by "Thread1"
    154 "Thread1":
    155   waiting to lock monitor 0x00bde724 (object 0x08fc4b28, a Dead2),
    156   which is held by "Thread2"
    157 
    158 Java stack information for the threads listed above:
    159 ===================================================
    160 "Thread2":
    161     at Dead1.test(TestDeadLock.java:25)
    162     - waiting to lock <0x08fc4b90> (a Dead1)
    163     at Dead2.test(TestDeadLock.java:52)
    164     - locked <0x08fc4b28> (a Dead2)
    165     at Dead2.run(TestDeadLock.java:43)
    166 "Thread1":
    167     at Dead2.test(TestDeadLock.java:47)
    168     - waiting to lock <0x08fc4b28> (a Dead2)
    169     at Dead1.test(TestDeadLock.java:30)
    170     - locked <0x08fc4b90> (a Dead1)
    171     at Dead1.run(TestDeadLock.java:21)
    172 
    173 Found 1 deadlock.

    看最后的红色字体,已经很清晰的说明了一切。

  • 相关阅读:
    十大编程算法助程序员走上高手之路
    软件流程图规范
    统一软件开发过程(rup)理解
    Java 数组基础
    软件开发生命周期模型 瀑布模型、增量模型、原型模型、螺旋模型、喷泉模型总结
    UML(5)——协作图
    时序图、活动图、状态图、协作图的区别
    面向对象分析设计-------02UML+UML各种图形及作用
    ExecutorService的十个使用技巧
    使用guava带来的方便
  • 原文地址:https://www.cnblogs.com/huashui/p/3757284.html
Copyright © 2011-2022 走看看