Analyzing deadlocks in Java applications with thread dumps
Recently I was given the task to analyze a problem with some multi-threaded Java application that got stuck if you run that application within a batch script again and again. On some invocations the application just did nothing (no CPU utilization, no exceptions). So how to analyze what the application is doing right now?
In cases like this, jstack enables you to create a thread dump for a running java application and gives a look inside. First you have to look up the id of the running application with jps and then provide its PID as the first argument to jstack:
C:\Users>jps 884 org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar 2344 Jps 5188 ThreadA C:\Users>jstack 5188 > stack.txt
As I opened the text file stack.txt, I found something like the following (reconstructed here with a simple example):
"Thread-18": at martin.ThreadB.run(ThreadB.java:13) - waiting to lock <0x00000000ec102070> (a java.lang.Object) "Thread-0": at martin.ThreadB.run(ThreadB.java:15) - waiting to lock <0x00000000ec103b68> (a java.lang.Object) - locked <0x00000000ec102070> (a java.lang.Object) "Thread-15": at martin.ThreadA.run(ThreadA.java:15) - waiting to lock <0x00000000ec102070> (a java.lang.Object) - locked <0x00000000ec103b68> (a java.lang.Object)
As you can see, Thread-18 is waiting to lock 0x00000000ec102070, which is already locked by Thread-0. Thread-0 on the other hand is waiting to lock 0x00000000ec103b68, which again is already locked (by Thread-15). And Thread-15 is also waiting to lock 0x00000000ec102070. Thus, we have a classic deadlock situation.