研究僵局–第3部分

在本系列的前兩個博客( 第1部分和第2部分)中 ,我演示了如何創建一段死鎖的不良代碼,然后使用該代碼展示了進行線程轉儲的三種方式。 在這個博客中,我將分析線程轉儲以找出錯誤的原因。

下面的討論同時涉及本系列第1部分中的AccountDeadlockDemo類,其中包含完整的代碼清單。

我需要做的第一件事是從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=5 tid=7f971216c000 nid=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=5 tid=7f9712943800 nid=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=5 tid=7f9712942800 nid=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=5 tid=7f9712942000 nid=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=5 tid=7f9712941000 nid=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=5 tid=7f9712940800 nid=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=5 tid=7f971293f800 nid=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=5 tid=7f97129ae000 nid=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=5 tid=7f97129ad000 nid=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=5 tid=7f97129ac800 nid=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=5 tid=7f97129ab800 nid=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=5 tid=7f97129ab000 nid=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=5 tid=7f97129aa000 nid=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=5 tid=7f97129a9800 nid=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=5 tid=7f97129a8800 nid=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=5 tid=7f97128a1800 nid=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=5 tid=7f97121af800 nid=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=5 tid=7f97121ae800 nid=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=5 tid=7f971224a000 nid=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=5 tid=7f97128fd800 nid=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=1 tid=7f97128fd000 nid=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=5 tid=7f971209e000 nid=0x1173ec000 runnable [00000000]
java.lang.Thread.State: RUNNABLE"C2 CompilerThread1" daemon prio=9 tid=7f971209d000 nid=0x1172e9000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE"C2 CompilerThread0" daemon prio=9 tid=7f971209c800 nid=0x1171e6000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE"Signal Dispatcher" daemon prio=9 tid=7f971209b800 nid=0x1170e3000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE"Surrogate Locker Thread (Concurrent GC)" daemon prio=5 tid=7f971209a800 nid=0x116fe0000 waiting on condition [00000000]
java.lang.Thread.State: RUNNABLE"Finalizer" daemon prio=8 tid=7f971209a000 nid=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=10 tid=7f9712099000 nid=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=9 tid=7f9712096800 nid=0x116b16000 runnable"Gang worker#0 (Parallel GC Threads)" prio=9 tid=7f9712002800 nid=0x1135c7000 runnable"Gang worker#1 (Parallel GC Threads)" prio=9 tid=7f9712003000 nid=0x1136ca000 runnable"Concurrent Mark-Sweep GC Thread" prio=9 tid=7f971204d800 nid=0x116790000 runnable
"VM Periodic Task Thread" prio=10 tid=7f97122d4000 nid=0x11793a000 waiting on condition"Exception Catcher Thread" prio=10 tid=7f9712001800 nid=0x1103ef000 runnable
JNI global references: 1037Found one Java-level deadlock:
=============================
"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:
===================================================
"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)

快速瀏覽,您可以看到此線程轉儲分為四個部分。 這些是:

  • 所有應用程序線程的完整列表
  • 死鎖線程列表
  • 一小堆死鎖線程
  • 應用程序的堆摘要


線程列表

上面第一點中的線程列表是所有應用程序線程及其當前狀態的列表。 從中您可以看到應用程序由一堆線程組成,您可以將它們大致分為兩部分。 首先,有后臺線程。 這些是每個應用程序所擁有的,而這些作為我們作為應用程序程序員通常不需要擔心的骯臟工作。 它們具有諸如“ DestroyJavaVM ”, 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 。 其次,您或我可能會在我們的代碼中創建一些線程。 這些名稱通常包含由單詞Thread和數字組成的名稱。 例如: Thread-3, Thread-6 and Thread-20.

"Thread-20" prio=5 tid=7f971216c000 nid=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上提供的信息,您會發現它可以分為幾部分。 這些是:

<td>線程20 <td>如上所述的線程名稱。<tr> <td> prio = 5 <td>線程的優先級。 從1到10的數字,其中1是最低優先級,10是最高優先級。 <tr> <tr> <td> tid = 7f971216c000 <td>線程ID。 Thread.getId()調用返回的唯一數字。 <tr> <td> nid = 0x118c73000 <td>本機線程ID。 這映射到平臺相關的線程ID。 <tr> <td>等待監視器輸入[118c72000]

java.lang.Thread.State:阻塞(在對象監視器上)<td>這是線程的狀態; 在這種情況下,它已被阻止。 還包括堆棧跟蹤概述了線程被阻塞的位置。

請注意,線程也可以標記為守護程序。 例如:
“ RMI TCP Accept-0”守護進程prio = 5 tid = 7f97128fd800 nid = 0x117837000可運行[117836000] java.lang.Thread.State:可運行
守護程序線程是后臺任務線程,例如上面列出的RMI TCP Accept-0線程。 守護程序線程是不會阻止JVM退出的線程。 僅保留守護程序線程時,JVM將退出或關閉。

但是,線程列表并不能真正幫助您找到死鎖的原因,因此請快速前進...

死鎖線程列表

線程轉儲的此部分包含死鎖中涉及的所有線程的列表。

Found one Java-level deadlock:
=============================
"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"

從上面的片段中,您可以看到有五個線程全部阻塞實例threads.deadlock.Account

撇開監視器ID和帳戶實例,您可以看到“線程21”正在等待“線程20”,它正在等待“線程4”,而后者又正在等待“線程7”。 “線程7”正在等待“線程11”,這正在等待“線程20”:死鎖循環,如下圖所示:

死鎖堆棧痕跡

難題的最后一部分是死鎖線程堆棧跟蹤的列表,如下所示:

Java stack information for the threads listed above:
===================================================
"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)

從上一節中,我們知道Thread-20正在通過a回路徑等待Thread-11Thread-11正在等待Thread-20 。 這是我們的僵局。

下一步是使用上面的線程堆棧跟蹤將此死鎖與代碼行聯系起來,我在下圖中對此進行了簡化。

在上圖中,為清楚起見,我從對象ID中刪除了7f3366前綴; 因此,對象7f3366f58現在是f58 。 從這個圖中,可以看到該對象f58被鎖定Thread-20上線59,并正在等待鎖對象e98上線86.箭頭下來,你可以看到, Thread-7正在等待鎖eb0上線86,而這又是通過鎖定Thread-11在線路59 Thread-11正在等待鎖f58上線86,其,循環備份,對線58通過鎖定Thread-20

那么,這些代碼行在哪里? 下面顯示了第59行:

…這是第86行:

有時每個人都會感到驚訝,上面的堆棧軌跡使我感到驚訝。 我期望鎖位于85和86行。 但是,它們分別在59和86上。由于第59行不包含synced關鍵字,因此我猜測編譯器已經對transfer(…)方法的第一個synced關鍵字進行了一些優化。

由此可以得出的結論是,從列表中隨機選擇兩個Account對象的代碼將它們以錯誤的順序鎖定在第59行和第86行。那么,解決方法是什么? 下次更多。 但是,還有最后一點需要注意,即每次在程序上生成線程轉儲時,死鎖的組成可能都不相同。 再次運行DeadlockDemo程序并使用kill -3 PID來獲取另一個線程轉儲后,我獲得了以下結果:

Found one Java-level deadlock:
=============================
"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:
===================================================
"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.

在此線程轉儲中,死鎖中涉及的線程數量較少,但是如果您對其進行分析,則可以得出與我的第一個示例相同的結論。

下次:修改代碼…

有關更多信息,請參閱本系列中的其他博客。

該系列以及其他博客的所有源代碼都可以在Github上找到,網址為git://github.com/roghughe/captaindebug.git

參考: 調查死鎖-第3部分: Captain Debug博客博客中來自JCG合作伙伴 Roger Hughes 的線程轉儲分析 。

翻譯自: https://www.javacodegeeks.com/2012/11/investigating-deadlocks-part-3.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/370937.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/370937.shtml
英文地址,請注明出處:http://en.pswp.cn/news/370937.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

qq2009顯ip版怎么用_毛孔粗大怎么破?用對方法,輕松改善顯皮膚嫩滑

臉上毛孔粗大怎么破&#xff1f;超級煩惱尤其是一到秋季臉上經常油膩膩的為什么會毛孔粗大呢&#xff1f;毛孔粗大怎么破&#xff1f;用對方法&#xff0c;輕松改善顯皮膚嫩滑 當皮膚老舊角質積聚越多&#xff0c;會使肌膚變厚、變粗糙&#xff0c;毛孔變粗大&#xff0c;肌膚也…

linux 賬號密碼 字段,詳解Linux中的用戶密碼管理命令passwd和change

passwd修改用戶密碼參數-k 保持未過期身份驗證令牌-l 關閉賬號密碼。效果相當于usermod -L&#xff0c;只有root才有權使用此項。-u 恢復賬號密碼。效果相當于usermod -U&#xff0c;同樣只有root才有權使用。-g 修改組密碼。gpasswd的等效命令。-f 更改由finger命令訪問的用戶…

hello程序的運行過程-從計算機系統角度

hello程序的運行過程-從計算機系統角度 1、gcc編譯器驅動程序讀取源程序文件hello.c&#xff0c;并將它翻譯成一個可執行目標文件hello。翻譯過程分為四個階段&#xff1a;預處理階段&#xff0c;編譯階段&#xff0c;匯編階段&#xff0c;鏈接階段。 2、初始時&#xff0c;she…

靠譜的div引入任何外鏈內容

靠譜的div引入任何外鏈內容 開發中經常要在div中引入一個頁面,該頁面可能是內部頁面,可能是一個外部頁面,也可能只是一個域名獲取的請求. 對于內部頁面的加載,建議使用jquery的load函數,如: 1 $("#targetId").load("someUrl/templatePage.html"); 對于外…

Eclipse對類固醇的重構

在上一篇有關常見Java違規的文章中 &#xff0c;我列出了Java開發人員容易犯的一系列錯誤。 在重構Java項目以解決這些違規問題的同時&#xff0c;我廣泛使用了Eclipse的重構功能來快速更改代碼。 下面是這種重構技術的匯編。 1.在塊級語句周圍添加花括號 用{curly braces}包裝…

微服務發展的歷史_“美麗新羌 光照未來” 新羌社區開展微視頻宣傳片拍攝活動...

見圳客戶端、深圳新聞網訊(記者 王志明 通訊員 甘力宇)為記錄新羌社區的歷史變遷&#xff0c;弘揚新羌人與時俱進、開拓進取的創新精神&#xff0c;宣傳社區黨委、社區一線工作者及社區居民的感人事跡和精神&#xff0c;展現深圳社區發展新風貌&#xff0c;2020年10月&#xff…

linux中掃描儀驅動程序,VueScan For Linux通用掃描儀驅動下載_VueScan For Linux通用掃描儀驅動官方下載-太平洋下載中心...

VueScan For Linux通用掃描儀驅動是一款提供 Linux 使用的圖片掃描工具&#xff0c;它具有各種高級硬件能力使用非常廣泛的的掃描儀軟件&#xff0c;支持EPSon、HP、Nikon 和Canon 品牌的掃描儀設備&#xff0c;具有優良的色彩保真度和色彩平衡&#xff0c;可以讓用戶比平板掃描…

HTML head 頭部中的各類標簽

HTML <head> 頭部 <head> 元素包含了所有的頭部標簽元素。在 <head>元素中你可以插入腳本&#xff08;scripts&#xff09;, 樣式文件&#xff08;CSS&#xff09;&#xff0c;及各種meta信息。 可以添加在頭部區域的元素標簽為: <title>, <style&g…

CSS變量(自定義屬性)實踐指南

本文翻譯自&#xff1a;https://www.sitepoint.com/practical-guide-css-variables-custom-properties/ 轉載請注明出處&#xff1a;葡萄城官網&#xff0c;葡萄城為開發者提供專業的開發工具、解決方案和服務&#xff0c;賦能開發者。 Sass和Less這樣的預處理器&#xff0c;讓…

避免使用FOR –反假戰役

您是否想知道FOR如何影響您的代碼&#xff1f; 他們如何限制您的設計&#xff0c;更重要的是如何將您的代碼轉換為無人為含義的多行代碼&#xff1f; 在這篇文章中&#xff0c;我們將看到如何將for的簡單示例&#xff08;由Francesco Cirillio提供- 反if活動&#xff09;轉換為…

ffmpeg-win32-v3.2.4 下載_MVBOX下載|MVBOX 7.1.0.4官方版

還是要強調一句&#xff0c;現在市面上很多盜版或者免費的軟件&#xff0c;都給一些黑客留下了暗門&#xff0c;所以大家還是支持正版比較好&#xff0c;不要貪圖便宜使用盜版軟件造成不好的后果。MVBOX播放器功能介紹1、在線卡拉OK2、虛擬攝像頭3、畫面調色板4、攝像頭摳像5、…

linux重啟鼠標鍵盤服務,Linux 關閉服務后 鼠標 鍵盤用不了

大部分情況下我們做實驗都是使用虛擬機&#xff0c;但是個人比較本實在太老了&#xff0c;性能有限&#xff0c;所以虛擬機里面的系統啟動神慢&#xff0c;怎么辦&#xff1f;把系統中自己用不到的服務全部關閉掉唄&#xff0c;如下for i in chkconfig --list | awk {print $1}…

拖拽功能-jquery

<!DOCTYPE html><html lang"en"><head> <meta charset"UTF-8"> <title>拖拽</title> <style> .nav { width: 200px; height: 200px; border: 1px solid blac…

PNG,GIF,JPG的區別及如何選

GIF&#xff1a; 1&#xff1a;256色 2&#xff1a; 無損&#xff0c;編輯 保存時候&#xff0c;不會損失。 3&#xff1a;支持簡單動畫。 4&#xff1a;支持boolean透明&#xff0c;也就是要么完全透明&#xff0c;要么不透明 JPEG&#xff1a; 1&#xff1a;millions o…

餓了么商家電腦版_餓了么企業版榮膺“2020中國十大影響力人力資源品牌”大獎...

11月6日&#xff0c;由MeetHR GROUP主辦的2020大中華地區HRVP高峰論壇在上海落幕。餓了么企業版憑借自身產品在人力資源管理與服務方面的創新實踐&#xff0c;榮獲“2020 中國十大影響力人力資源品牌(薪酬福利類)”殊榮。本次評選&#xff0c;據主辦方介紹&#xff0c;旨在激勵…

用信號量鎖定:一個例子

并發是帶來有趣挑戰的一個方面。 如果處理不當&#xff0c;會導致種族狀況&#xff0c;這會使人們感到困惑&#xff0c;因為這些問題有時會突然出現&#xff0c;并且有時會完美無缺地發揮作用。 當處理訪問公共資源的并發線程時&#xff0c;Java語言提供了許多處理競爭條件的方…

navicat連接linux遠程數據庫,使用Navicat forMySql遠程連接Linux 系統上的數據庫

使用Navicat for MySql遠程連接Linux 系統上的數據庫解決mysql"Access denied for userrootIP地址"問題1.問題說明&#xff1a;在MYSQL 中&#xff0c;用遠程軟件登陸服務器&#xff0c;有時出現&#xff1a;Access denied for user rootlocalhost出現這種問題&#…

HTTPS 通俗簡介

為什么需要HTTPS 9個問題搞懂 https 來源 HTTP是明文傳輸的&#xff0c;也就意味著&#xff0c;介于發送端、接收端中間的任意節點都可以知道你們傳輸的內容是什么。這些節點可能是路由器、代理 等。 舉個最常見的例子&#xff0c;用戶登陸。用戶輸入賬號&#xff0c;密碼&am…

CSS Modules入門教程

為什么引入CSS Modules 或者可以這么說&#xff0c;CSS Modules為我們解決了什么痛點。針對以往我寫網頁樣式的經驗&#xff0c;具體來說可以歸納為以下幾點&#xff1a; 全局樣式沖突 過程是這樣的&#xff1a;你現在有兩個模塊&#xff0c;分別為A、B,你可能會單獨針對這兩…

單點登錄(一):思考

單點登錄&#xff08;后文簡稱&#xff1a;sso&#xff09;的定義是在多個應用系統中&#xff0c;用戶只需要登錄一次就可以訪問所有相互信任的應用系統&#xff08;摘自百度百科&#xff09;。整個流程中涉及到的角色有&#xff1a;用戶。應用服務器&#xff0c;即業務系統。單…