Java死锁 Thread Dump分析详解编程语言
2023-06-13 09:11:51 时间
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 } 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 } 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): 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) 20 Locked ownable synchronizers: 21 - 0x090afed0 (a java.util.concurrent.ThreadPoolExecutor$Worker) 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) 31 Locked ownable synchronizers: 32 - None 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) 47 Locked ownable synchronizers: 48 - None 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) 64 Locked ownable synchronizers: 65 - None 67 "DestroyJavaVM" prio=6 tid=0x005fb000 nid=0x19f4 waiting on condition [0x00000000] 68 java.lang.Thread.State: RUNNABLE 70 Locked ownable synchronizers: 71 - None 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) 81 Locked ownable synchronizers: 82 - None 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) 92 Locked ownable synchronizers: 93 - None 95 "Service Thread" daemon prio=6 tid=0x00c65000 nid=0x7c8 runnable [0x00000000] 96 java.lang.Thread.State: RUNNABLE 98 Locked ownable synchronizers: 99 - None 101 "C1 CompilerThread0" daemon prio=10 tid=0x00c58400 nid=0x193c waiting on condition [0x00000000] 102 java.lang.Thread.State: RUNNABLE 104 Locked ownable synchronizers: 105 - None 107 "Attach Listener" daemon prio=10 tid=0x00c53000 nid=0x110c waiting on condition [0x00000000] 108 java.lang.Thread.State: RUNNABLE 110 Locked ownable synchronizers: 111 - None 113 "Signal Dispatcher" daemon prio=10 tid=0x00c50000 nid=0x1900 runnable [0x00000000] 114 java.lang.Thread.State: RUNNABLE 116 Locked ownable synchronizers: 117 - None 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) 128 Locked ownable synchronizers: 129 - None 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) 139 Locked ownable synchronizers: 140 - None 142 "VM Thread" prio=10 tid=0x00bd5400 nid=0x140c runnable 144 "VM Periodic Task Thread" prio=10 tid=0x00c76400 nid=0x1978 waiting on condition 146 JNI global references: 192 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" 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) 173 Found 1 deadlock.
看最后的红色字体,已经很清晰的说明了一切。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/19412.html
cjava相关文章
- java环境_Java基础篇——环境配置
- Java中的锁
- 【Java】Best coding practices every java developer should
- 【Java 集合】Java 集合的线程安全性 ( 加锁同步 | java.utils 集合 | 集合属性 | java.util.concurrent 集合 | CopyOnWrite 机制 )
- java复习基础篇——网络协议详解编程语言
- Java CountDownLatch示例代码详解编程语言
- 在java代码中将图片转变为base64位代码 并且在浏览器下展示base64编码的图片详解编程语言
- java操作csv文件相关代码详解编程语言
- 把 Java util.Date 转成 sql.Date详解编程语言
- JAVA导出成CSV文件详解编程语言
- java.lang.String (JDK1.8)详解编程语言
- java基础学习总结——接口详解编程语言
- java虚拟机如何操作缓冲区详解编程语言
- Java基础之多线程实例详解编程语言
- 【Java并发编程(1)】:可重入内置锁详解编程语言
- [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义详解编程语言
- Java List/Set/Map详解编程语言
- Java反射机制详解编程语言
- java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener详解编程语言
- Java中文验证码详解编程语言
- MySQL封装之Java实现(mysql封装java)
- Java ftp上传文件方法效率对比详解编程语言
- Java之网络爬虫WebCollector2.1.2+selenium2.44+phantomjs2.1.1详解编程语言
- java内存模型详解编程语言
- Java NIO(1):浅谈I/O模型详解编程语言
- java 中的 各种变量、代码块执行时机详解编程语言
- Java图片压缩详解编程语言
- 七大排序的Java实现(插入+希尔+冒泡+快速+选择+堆+归并)详解编程语言
- 如何在Linux系统下成功安装Java?(linux下安装java)
- Java实现Linux:跨平台解决方案(java 实现linux)
- 编程玩转Java之Oracle编程实战(java中的oracle)