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:

Java死锁 Thread 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.

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

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/19412.html

(0)
上一篇 2021年7月19日 22:09
下一篇 2021年7月19日 22:09

相关推荐

发表回复

登录后才能评论