以下にデッドロックのサンプルプログラムと、スレッドダンプの出力例を示します。
スレッドダンプの解析方法は、“チューニングガイド”の“JDK/JREのチューニング”の“スレッドダンプ”を参照してください。
■サンプルプログラム
------------------------------------------------------------------------------- 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()メソッドはロックを獲得できずに、ハングアップします。
■スレッドダンプの出力例
JDK6におけるスレッドダンプの出力例を次に示します。
------------------------------------------------------------------------------- **************************************************************** Java Thread dump Tool for WindowsNT/2000/XP Copyright(c) 2002 FUJITSU LIMITED. All rights reserved. start at Tue Jan 11 10:38:25 2011 cmd = C:\Interstage\JDK6\bin\java.exe Deadlock Memory usage (Free/Total) = 7470040/7864320 (bytes) (ProcessId = 0x754, Tool ThreadId = 0xe98) **************************************************************** Full thread dump Java HotSpot(TM) Server VM (17.1.03_FUJITSU_MODIFIED-B11 mixed mode): [pid=1876] Time=Tue Jan 11 10:38:25 2011 "Java Thread dump tool" prio=10 tid=0x03c0f800 nid=0xe98 waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "Child" prio=6 tid=0x03c0e000 nid=0xbec waiting on condition [0x045cf000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at Deadlock.run(Deadlock.java:8) - locked <0x0fd98740> (a Deadlock) at java.lang.Thread.run(Thread.java:619) "Low Memory Detector" daemon prio=6 tid=0x03bf9000 nid=0x918 runnable [0x00000000] java.lang.Thread.State: RUNNABLE "CompilerThread1" daemon prio=10 tid=0x03c08800 nid=0x59c waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "CompilerThread0" daemon prio=10 tid=0x03c03800 nid=0xb5c waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "Attach Listener" daemon prio=10 tid=0x03e49800 nid=0x2b8 runnable [0x00000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" daemon prio=10 tid=0x03e5a800 nid=0x2fc runnable [0x00000000] java.lang.Thread.State: RUNNABLE "Finalizer" daemon prio=8 tid=0x03bea800 nid=0x170 in Object.wait() [0x03e3f000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x0fd60b18> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118) - locked <0x0fd60b18> (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=0x03be5c00 nid=0xb04 in Object.wait() [0x03def000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x0fd60a20> (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 <0x0fd60a20> (a java.lang.ref.Reference$Lock) "main" prio=6 tid=0x00317000 nid=0xe80 waiting for monitor entry [0x0093f000] java.lang.Thread.State: BLOCKED (on object monitor) at Deadlock.main(Deadlock.java:25) - waiting to lock <0x0fd98740> (a Deadlock) "VM Thread" prio=10 tid=0x03be2c00 nid=0xd34 runnable "GC task thread#0 (ParallelGC)" prio=6 tid=0x0031e800 nid=0xc84 runnable "GC task thread#1 (ParallelGC)" prio=6 tid=0x03b10400 nid=0xaa4 runnable "GC task thread#2 (ParallelGC)" prio=6 tid=0x03b11400 nid=0xe7c runnable "GC task thread#3 (ParallelGC)" prio=6 tid=0x03b12800 nid=0x480 runnable "VM Periodic Task Thread" prio=10 tid=0x03bfac00 nid=0xe88 waiting on condition "RAS Control Thread" prio=10 tid=0x03be2000 nid=0xb4c runnable JNI global references: 854 Heap PSYoungGen total 3584K, used 385K [0x0fd60000, 0x10160000, 0x10470000) eden space 3072K, 12% used [0x0fd60000,0x0fdc0428,0x10060000) from space 512K, 0% used [0x100e0000,0x100e0000,0x10160000) to space 512K, 0% used [0x10060000,0x10060000,0x100e0000) PSOldGen total 4096K, used 0K [0x0c470000, 0x0c870000, 0x0fd60000) object space 4096K, 0% used [0x0c470000,0x0c470000,0x0c870000) PSPermGen total 16384K, used 2012K [0x08470000, 0x09470000, 0x0c470000) object space 16384K, 12% used [0x08470000,0x08667288,0x09470000) **************************************************************** Java Thread dump end **************************************************************** -------------------------------------------------------------------------------