以下にデッドロックのサンプルプログラムと、スレッドダンプの出力例を示します。
スレッドダンプの解析方法は、“チューニングガイド” を参照してください。
JDK/JRE 7
“JDK/JRE 7のチューニング” - “スレッドダンプ”
JDK/JRE 8
“JDK/JRE 8のチューニング” - “スレッドダンプ”
サンプルプログラム
------------------------------------------------------------------------------- public class Deadlock implements Runnable { volatile boolean finished = false; public void run() { try { synchronized (this) { while (!finished) { System.out.print("."); Thread.sleep(500); } } } catch (InterruptedException ex) { ex.printStackTrace(System.out); Thread.currentThread().interrupt(); } } public static void main(String args[]) { Object obj = new Object(); Deadlock test = new Deadlock(); Thread th = new Thread(test, "Child"); try { th.start(); Thread.sleep(5000); synchronized (test) { test.finished = true; } } catch (Exception ex) { ex.printStackTrace(System.out); } } } -------------------------------------------------------------------------------
このサンプルプログラムは、run()メソッドで、DeadLockクラスのインスタンスに対して、synchronized句によりロックを取得しています。run()メソッドは、finishedフラグがfalseの間ループを繰り返します。一方、main()メソッドは、run()メソッド呼出し後に、DeadLockクラスのインスタンスに対してロックを獲得できたならば、finishedフラグをtrueに設定します。
この例の場合、run()メソッドが、DeadLockクラスのインスタンスに対してロックを獲得していますので、main()メソッドはロックを獲得できずに、ハングアップします。
スレッドダンプの出力例
JDK8におけるスレッドダンプの出力例を次に示します。
------------------------------------------------------------------------------- **************************************************************** Java Thread dump Tool Copyright(c) 2002-2016 FUJITSU LIMITED. All rights reserved. start at Tue Mar 21 10:44:29 2017 cmd = C:\Interstage\JDK8\bin\java.exe Deadlock Memory usage (Free/Total) = 5358640/6094848 (bytes) (ProcessId = 0x121c, Tool ThreadId = 0x13cc) **************************************************************** 2017-03-21 10:44:29 Full thread dump Java HotSpot(TM) Client VM (1.8.0_121_FUJITSU_MODIFIED-B09[25.121.13] mixed mode): "Java Thread dump tool" #9 prio=5 os_prio=15 tid=0x0abc2400 nid=0x13cc waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "Child" #8 prio=5 os_prio=0 tid=0x0abc1400 nid=0xcb4 waiting on condition [0x0b15f000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at Deadlock.run(Deadlock.java:8) - locked <0x046a1f00> (a Deadlock) at java.lang.Thread.run(Thread.java:745) "Service Thread" #7 daemon prio=9 os_prio=0 tid=0x0aa96400 nid=0xb94 runnable [0x00000000] java.lang.Thread.State: RUNNABLE "C1 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x0aa8f000 nid=0xedc waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0aa87800 nid=0xa54 runnable [0x00000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0aa86800 nid=0xc6c runnable [0x00000000] java.lang.Thread.State: RUNNABLE "Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0aa77c00 nid=0xefc in Object.wait() [0x0ad7f000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x04607ee0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) - locked <0x04607ee0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) "Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00d4ec00 nid=0xb70 in Object.wait() [0x0acef000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x04605f68> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x04605f68> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) "main" #1 prio=5 os_prio=0 tid=0x006fb400 nid=0x1074 waiting for monitor entry [0x008af000] java.lang.Thread.State: BLOCKED (on object monitor) at Deadlock.main(Deadlock.java:25) - waiting to lock <0x046a1f00> (a Deadlock) "VM Thread" os_prio=2 tid=0x00d4b000 nid=0x1128 runnable "VM Periodic Task Thread" os_prio=2 tid=0x0aadc000 nid=0xd30 waiting on condition JNI global references: 6 Heap def new generation total 1856K, used 718K [0x04600000, 0x04800000, 0x06600000) eden space 1664K, 43% used [0x04600000, 0x046b3bd0, 0x047a0000) from space 192K, 0% used [0x047a0000, 0x047a0000, 0x047d0000) to space 192K, 0% used [0x047d0000, 0x047d0000, 0x04800000) tenured generation total 4096K, used 0K [0x06600000, 0x06a00000, 0x0a600000) the space 4096K, 0% used [0x06600000, 0x06600000, 0x06600200, 0x06a00000) Metaspace used 1752K, capacity 2242K, committed 2368K, reserved 4480K **************************************************************** Java Thread dump end **************************************************************** -------------------------------------------------------------------------------