windows10僵局
在本系列的前两个博客(第1部分和第2部分)中,我演示了如何创建一段死锁的不良代码,然后使用该代码演示进行线程转储的三种方式。 在此博客中,我将分析线程转储以找出错误的原因。
下面的讨论同时涉及本系列第1部分中的Account
和DeadlockDemo
类,其中包含完整的代码清单。
我需要做的第一件事是从DeadlockDemo
应用程序中进行线程转储,就像他们以前在Blue Peter上所说的那样:“这是我之前准备的”。
2012-10-16 13:37:03
Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.10-b01-428 mixed mode):"DestroyJavaVM" prio=5 tid=7f9712001000 nid=0x110247000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE"Thread-21" prio=5 tid=7f9712944000 nid=0x118d76000 waiting for monitor entry [118d75000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366f58> (a threads.deadlock.Account)
- locked <7f3366ee0> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-20" prio&#61;5 tid&#61;7f971216c000 nid&#61;0x118c73000 waiting for monitor entry [118c72000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366e98> (a threads.deadlock.Account)
- locked <7f3366f58> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-19" prio&#61;5 tid&#61;7f9712943800 nid&#61;0x118b70000 waiting for monitor entry [118b6f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:81)
- waiting to lock <7f3366f40> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-18" prio&#61;5 tid&#61;7f9712942800 nid&#61;0x118a6d000 waiting for monitor entry [118a6c000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:81)
- waiting to lock <7f3366f40> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-17" prio&#61;5 tid&#61;7f9712942000 nid&#61;0x11896a000 waiting for monitor entry [118969000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:81)
- waiting to lock <7f3366ec8> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-16" prio&#61;5 tid&#61;7f9712941000 nid&#61;0x118867000 waiting for monitor entry [118866000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:81)
- waiting to lock <7f3366ec8> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-15" prio&#61;5 tid&#61;7f9712940800 nid&#61;0x118764000 waiting for monitor entry [118763000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:81)
- waiting to lock <7f3366ef8> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-14" prio&#61;5 tid&#61;7f971293f800 nid&#61;0x118661000 waiting for monitor entry [118660000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:81)
- waiting to lock <7f3366f28> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-13" prio&#61;5 tid&#61;7f97129ae000 nid&#61;0x11855e000 waiting for monitor entry [11855d000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:81)
- waiting to lock <7f3366eb0> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-12" prio&#61;5 tid&#61;7f97129ad000 nid&#61;0x11845b000 waiting for monitor entry [11845a000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:81)
- waiting to lock <7f3366f40> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-11" prio&#61;5 tid&#61;7f97129ac800 nid&#61;0x118358000 waiting for monitor entry [118357000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366f58> (a threads.deadlock.Account)
- locked <7f3366eb0> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-10" prio&#61;5 tid&#61;7f97129ab800 nid&#61;0x118255000 waiting for monitor entry [118254000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:81)
- waiting to lock <7f3366eb0> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-9" prio&#61;5 tid&#61;7f97129ab000 nid&#61;0x118152000 waiting for monitor entry [118151000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366e98> (a threads.deadlock.Account)
- locked <7f3366ec8> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-8" prio&#61;5 tid&#61;7f97129aa000 nid&#61;0x11804f000 waiting for monitor entry [11804e000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366eb0> (a threads.deadlock.Account)
- locked <7f3366f28> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-7" prio&#61;5 tid&#61;7f97129a9800 nid&#61;0x117f4c000 waiting for monitor entry [117f4b000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366eb0> (a threads.deadlock.Account)
- locked <7f3366e80> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-6" prio&#61;5 tid&#61;7f97129a8800 nid&#61;0x117e49000 waiting for monitor entry [117e48000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:81)
- waiting to lock <7f3366e80> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-5" prio&#61;5 tid&#61;7f97128a1800 nid&#61;0x117d46000 waiting for monitor entry [117d45000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:81)
- waiting to lock <7f3366f28> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-4" prio&#61;5 tid&#61;7f97121af800 nid&#61;0x117c43000 waiting for monitor entry [117c42000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366e80> (a threads.deadlock.Account)
- locked <7f3366e98> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-3" prio&#61;5 tid&#61;7f97121ae800 nid&#61;0x117b40000 waiting for monitor entry [117b3f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366e80> (a threads.deadlock.Account)
- locked <7f3366ef8> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"Thread-2" prio&#61;5 tid&#61;7f971224a000 nid&#61;0x117a3d000 waiting for monitor entry [117a3c000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366eb0> (a threads.deadlock.Account)
- locked <7f3366f40> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)"RMI TCP Accept-0" daemon prio&#61;5 tid&#61;7f97128fd800 nid&#61;0x117837000 runnable [117836000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
- locked <7f32ee740> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:34)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:369)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:341)
at java.lang.Thread.run(Thread.java:680)"Poller SunPKCS11-Darwin" daemon prio&#61;1 tid&#61;7f97128fd000 nid&#61;0x117734000 waiting on condition [117733000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at sun.security.pkcs11.SunPKCS11$TokenPoller.run(SunPKCS11.java:692)
at java.lang.Thread.run(Thread.java:680)"Low Memory Detector" daemon prio&#61;5 tid&#61;7f971209e000 nid&#61;0x1173ec000 runnable [00000000]
java.lang.Thread.State: RUNNABLE"C2 CompilerThread1" daemon prio&#61;9 tid&#61;7f971209d000 nid&#61;0x1172e9000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE"C2 CompilerThread0" daemon prio&#61;9 tid&#61;7f971209c800 nid&#61;0x1171e6000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE"Signal Dispatcher" daemon prio&#61;9 tid&#61;7f971209b800 nid&#61;0x1170e3000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE"Surrogate Locker Thread (Concurrent GC)" daemon prio&#61;5 tid&#61;7f971209a800 nid&#61;0x116fe0000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE"Finalizer" daemon prio&#61;8 tid&#61;7f971209a000 nid&#61;0x116d1c000 in Object.wait() [116d1b000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <7f3001300> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <7f3001300> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)"Reference Handler" daemon prio&#61;10 tid&#61;7f9712099000 nid&#61;0x116c19000 in Object.wait() [116c18000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <7f30011d8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <7f30011d8> (a java.lang.ref.Reference$Lock)"VM Thread" prio&#61;9 tid&#61;7f9712096800 nid&#61;0x116b16000 runnable"Gang worker#0 (Parallel GC Threads)" prio&#61;9 tid&#61;7f9712002800 nid&#61;0x1135c7000 runnable"Gang worker#1 (Parallel GC Threads)" prio&#61;9 tid&#61;7f9712003000 nid&#61;0x1136ca000 runnable"Concurrent Mark-Sweep GC Thread" prio&#61;9 tid&#61;7f971204d800 nid&#61;0x116790000 runnable
"VM Periodic Task Thread" prio&#61;10 tid&#61;7f97122d4000 nid&#61;0x11793a000 waiting on condition"Exception Catcher Thread" prio&#61;10 tid&#61;7f9712001800 nid&#61;0x1103ef000 runnable
JNI global references: 1037Found one Java-level deadlock:
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
"Thread-21":
waiting to lock monitor 7f97118bd560 (object 7f3366f58, a threads.deadlock.Account),
which is held by "Thread-20"
"Thread-20":
waiting to lock monitor 7f97118bc108 (object 7f3366e98, a threads.deadlock.Account),
which is held by "Thread-4"
"Thread-4":
waiting to lock monitor 7f9711834360 (object 7f3366e80, a threads.deadlock.Account),
which is held by "Thread-7"
"Thread-7":
waiting to lock monitor 7f97118b9708 (object 7f3366eb0, a threads.deadlock.Account),
which is held by "Thread-11"
"Thread-11":
waiting to lock monitor 7f97118bd560 (object 7f3366f58, a threads.deadlock.Account),
which is held by "Thread-20"Java stack information for the threads listed above:
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
"Thread-21":
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366f58> (a threads.deadlock.Account)
- locked <7f3366ee0> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)
"Thread-20":
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366e98> (a threads.deadlock.Account)
- locked <7f3366f58> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)
"Thread-4":
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366e80> (a threads.deadlock.Account)
- locked <7f3366e98> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)
"Thread-7":
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366eb0> (a threads.deadlock.Account)
- locked <7f3366e80> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)
"Thread-11":
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366f58> (a threads.deadlock.Account)
- locked <7f3366eb0> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)Found 1 deadlock.Heap
par new generation total 19136K, used 11590K [7f3000000, 7f44c0000, 7f44c0000)
eden space 17024K, 68% used [7f3000000, 7f3b51ac0, 7f40a0000)
from space 2112K, 0% used [7f40a0000, 7f40a0000, 7f42b0000)
to space 2112K, 0% used [7f42b0000, 7f42b0000, 7f44c0000)
concurrent mark-sweep generation total 63872K, used 0K [7f44c0000, 7f8320000, 7fae00000)
concurrent-mark-sweep perm gen total 21248K, used 8268K [7fae00000, 7fc2c0000, 800000000)
快速浏览&#xff0c;您可以看到此线程转储分为四个部分。 这些是&#xff1a;
- 所有应用程序线程的完整列表
- 死锁线程列表
- 一小堆死锁线程
- 应用程序的堆摘要
线程列表
上面第一点中的线程列表是所有应用程序线程及其当前状态的列表。 从中您可以看到应用程序由一堆线程组成&#xff0c;您可以将它们大致分为两部分。 首先是后台线程。 这些是每个应用程序所拥有的&#xff0c;而这些作为我们作为应用程序程序员通常不需要担心的肮脏工作。 它们具有诸如“ DestroyJavaVM
”&#xff0c; Low Memory Detector, Finalizer, Exception Catcher Thread and Concurrent Mark-Sweep GC Thread
DestroyJavaVM
Low Memory Detector, Finalizer, Exception Catcher Thread and Concurrent Mark-Sweep GC Thread
。 其次&#xff0c;您或我可能会在我们的代码中创建一些线程。 这些名称通常包含由单词Thread
和数字组成的名称。 例如&#xff1a; Thread-3, Thread-6 and Thread-20.
"Thread-20" prio&#61;5 tid&#61;7f971216c000 nid&#61;0x118c73000 waiting for monitor entry [118c72000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:82)
- waiting to lock <7f3366e98> (a threads.deadlock.Account)
- locked <7f3366f58> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:58)
详细查看Thread-20上提供的信息&#xff0c;您会发现它可以分为几部分。 这些是&#xff1a;
java.lang.Thread.State&#xff1a;阻塞(在对象监视器上)
请注意&#xff0c;线程也可以标记为守护程序。 例如&#xff1a; “ RMI TCP Accept-0”守护程序prio &#61; 5 tid &#61; 7f97128fd800 nid &#61; 0x117837000可运行[117836000] java.lang.Thread.State&#xff1a;可运行守护程序线程是后台任务线程&#xff0c;例如上面列出的RMI TCP Accept-0线程。 守护程序线程是不会阻止JVM退出的线程。 仅保留守护程序线程时&#xff0c;JVM将退出或关闭。但是&#xff0c;线程列表并不能真正帮助您找到死锁的原因&#xff0c;因此请快速前进……
死锁线程列表
线程转储的此部分包含死锁中涉及的所有线程的列表。
Found one Java-level deadlock:
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
"Thread-21":
waiting to lock monitor 7f97118bd560 (object 7f3366f58, a threads.deadlock.Account),
which is held by "Thread-20"
"Thread-20":
waiting to lock monitor 7f97118bc108 (object 7f3366e98, a threads.deadlock.Account),
which is held by "Thread-4"
"Thread-4":
waiting to lock monitor 7f9711834360 (object 7f3366e80, a threads.deadlock.Account),
which is held by "Thread-7"
"Thread-7":
waiting to lock monitor 7f97118b9708 (object 7f3366eb0, a threads.deadlock.Account),
which is held by "Thread-11"
"Thread-11":
waiting to lock monitor 7f97118bd560 (object 7f3366f58, a threads.deadlock.Account),
which is held by "Thread-20"
从上面的片段中&#xff0c;您可以看到有五个线程在实例threads.deadlock.Account
类上全部阻塞
除去监视器ID和帐户实例&#xff0c;您可以看到“线程21”正在等待“线程20”&#xff0c;它正在等待“线程4”&#xff0c;而后者又在等待“线程7”。 “ Thread-7”正在等待“ Thread-11”&#xff0c;这正在等待“ Thread-20”&#xff1a;死锁循环&#xff0c;如下图所示&#xff1a;
死锁堆栈痕迹难题的最后一部分是死锁线程堆栈跟踪的列表&#xff0c;如下所示&#xff1a;
Java stack information for the threads listed above:
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
"Thread-21":
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366f58> (a threads.deadlock.Account)
- locked <7f3366ee0> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)
"Thread-20":
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366e98> (a threads.deadlock.Account)
- locked <7f3366f58> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)
"Thread-4":
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366e80> (a threads.deadlock.Account)
- locked <7f3366e98> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)
"Thread-7":
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366eb0> (a threads.deadlock.Account)
- locked <7f3366e80> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)
"Thread-11":
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f3366f58> (a threads.deadlock.Account)
- locked <7f3366eb0> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)
从上一节中&#xff0c;我们知道Thread-20
正在通过a回路径等待Thread-11
而Thread-11
正在等待Thread-20
。 这是我们的僵局。
下一步是使用上面的线程堆栈跟踪将此死锁与代码行联系起来&#xff0c;我在下图中对此进行了简化。
在上图中&#xff0c;为了清楚起见&#xff0c;我从对象ID中删除了7f3366
前缀。 因此&#xff0c;对象7f3366f58
现在是f58
。 从这个图中&#xff0c;可以看到该对象f58
被锁定Thread-20
上线59&#xff0c;并正在等待锁对象e98
上线86.箭头下来&#xff0c;你可以看到&#xff0c; Thread-7
正在等待锁eb0
上线86&#xff0c;而这又是通过锁定Thread-11
在线路59 Thread-11
正在等待锁f58
上线86&#xff0c;其&#xff0c;循环备份&#xff0c;对线58通过锁定Thread-20
。
那么&#xff0c;这些代码行在哪里&#xff1f; 下面显示了第59行&#xff1a;
…这是第86行&#xff1a;
有时每个人都会感到惊讶&#xff0c;上面的堆栈痕迹使我感到惊讶。 我期望锁位于85和86行。 但是&#xff0c;它们分别在59和86上。由于第59行不包含synced关键字&#xff0c;因此我猜测编译器已经对transfer(…)方法的第一个synced关键字进行了一些优化。
由此得出的结论是&#xff0c;从列表中随机选择两个Account
对象的代码将它们以错误的顺序锁定在第59行和第86行。那么&#xff0c;解决方法是什么&#xff1f; 下次再说&#xff1b; 但是&#xff0c;还有最后一点需要注意&#xff0c;即每次在程序上生成线程转储时&#xff0c;死锁的组成可能都不相同。 再次运行DeadlockDemo
程序并使用kill -3
PID来获取另一个线程转储时&#xff0c;我获得了以下结果&#xff1a;
Found one Java-level deadlock:
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
"Thread-20":
waiting to lock monitor 7fdc7c802508 (object 7f311a530, a threads.deadlock.Account),
which is held by "Thread-3"
"Thread-3":
waiting to lock monitor 7fdc7a83d008 (object 7f311a518, a threads.deadlock.Account),
which is held by "Thread-11"
"Thread-11":
waiting to lock monitor 7fdc7c802508 (object 7f311a530, a threads.deadlock.Account),
which is held by "Thread-3"Java stack information for the threads listed above:
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
"Thread-20":
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:86)
- waiting to lock <7f311a530> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)
"Thread-3":
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:87)
- waiting to lock <7f311a518> (a threads.deadlock.Account)
- locked <7f311a530> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)
"Thread-11":
at threads.deadlock.DeadlockDemo$BadTransferOperation.transfer(DeadlockDemo.java:87)
- waiting to lock <7f311a530> (a threads.deadlock.Account)
- locked <7f311a518> (a threads.deadlock.Account)
at threads.deadlock.DeadlockDemo$BadTransferOperation.run(DeadlockDemo.java:59)Found 1 deadlock.
在此线程转储中&#xff0c;死锁涉及的线程数量较少&#xff0c;但是如果您分析死锁&#xff0c;则可以得出与我的第一个示例相同的结论。
下次&#xff1a;修改代码…
有关更多信息&#xff0c;请参阅本系列中的其他博客。
该系列以及其他博客的所有源代码都可以在Github上找到&#xff0c;网址为git&#xff1a;//github.com/roghughe/captaindebug.git
参考&#xff1a;调查死锁-第3部分&#xff1a;在Captain Debug的Blog博客上分析来自JCG合作伙伴Roger Hughes的线程转储。
翻译自: https://www.javacodegeeks.com/2012/11/investigating-deadlocks-part-3.html
windows10僵局
-
先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]本文介绍了如何搭建Java开发环境并开发WinCE项目,包括搭建开发环境的步骤和获取SDK的几种方式。同时还解答了一些关于WinCE开发的常见问题。通过阅读本文,您将了解如何使用Java进行嵌入式开发,并能够顺利开发WinCE应用程序。 ... [详细]本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]Tags | 热门标签RankList | 热门文章
- 1在Windows 8上安装gvim中的插件的错误加载问题
- 2mysql分组排序_在MySQL中实现分组排序功能
- 3CSS3选择器的使用方法详解,提高Web开发效率和精准度
- 4从二叉树中随机选择节点
- 5关于正则的一个困惑:为什么这个函数会获取parent下所有的节点?
- 6Java工具类库Hutool介绍及功能概述
- 7android listview OnItemClickListener失效原因
- 8Alink回归预测的不完善问题及期待
- 9jqPlot折线图插件的功能和用法详解
- 10C#生成随机数的三种方法及其问题分析
- 11微店分销产品如何修改价格和设置价格的方法
- 12如何限制php数据库链接数和连接超时时间?
- 13Redis数据结构之string应用场景解析
- 14Centos7.6安装Gitlab教程及注意事项
- 15如何使用Java获取服务器硬件信息和磁盘负载率