How to analyze Java thread dumps to find blocked threads

What is Thread dump?

A Java thread dump is a snapshot of what all the threads are doing in the JVM at the particular time we send the request of the dump. The Java thread dump results contains a lot of information, that is, each thread in the JVM is listed with its name, id, current state and the Java call stack

Tools to get Thread dump

There are many tools in the market which help developers in getting the thread dump. jvisualvm(Java VisualVM) comes bundled with the Java platform and can be used to get thread dumps.

 

Sample code with blocked threads

Here is the sample java code which will result into a deadlock

We have two thread classes T1 and T2. In the main class we created 2 threads of each class, t1 and t2. We also have 2 class level lock objects lock1 and lock2. Thread t1 will acquire lock1 first and then go to sleep. Similarly thread t2 will acquire lock2 and then go to sleep. Once both thread wake up they will require the lock2 and lock1 respectively which are already acquired. So this code will go into a deadlock

Output of the code will be ‘Outer lock1 captured Outer lock2 captured’ followed by hung state and deadlock

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public class Deadlock {
 
	public static Object Lock1 = new Object();
	public static Object Lock2 = new Object();
 
	public static void main(String[] args) {
		T1 t1 = new T1();
		t1.start();
 
		T2 t2 = new T2();
		t2.start();
 
	}
 
	private static class T1 extends Thread {
 
		@Override
		public void run() {
			synchronized (Lock1) {
				System.out.print("Outer lock1 captured");
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
 
				synchronized (Lock2) {
					System.out.print("Inner lock2 captured");
 
				}
			}
 
		}
 
	}
 
	private static class T2 extends Thread {
 
		@Override
		public void run() {
			synchronized (Lock2) {
				System.out.print("Outer lock2 captured");
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
 
				synchronized (Lock1) {
					System.out.print("Inner lock1 captured");
 
				}
			}
 
		}
 
	}
}

 

Thread dump

 

So this is how the thread dump will look like.

“DestroyJavaVM” #12 prio=5 os_prio=0 tid=0x0000000002372800 nid=0x67e0 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
– None

“Thread-1” #11 prio=5 os_prio=0 tid=0x0000000019f10800 nid=0x415c waiting for monitor entry [0x000000001a68f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at Deadlock$T2.run(Deadlock.java:53)
– waiting to lock <0x00000000d5d92248> (a java.lang.Object)
– locked <0x00000000d5d92258> (a java.lang.Object)

Locked ownable synchronizers:
– None

“Thread-0” #10 prio=5 os_prio=0 tid=0x0000000019f10000 nid=0x5240 waiting for monitor entry [0x000000001a58f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at Deadlock$T1.run(Deadlock.java:30)
– waiting to lock <0x00000000d5d92258> (a java.lang.Object)
– locked <0x00000000d5d92248> (a java.lang.Object)

Locked ownable synchronizers:
– None

“Service Thread” #9 daemon prio=9 os_prio=0 tid=0x0000000019e97000 nid=0x5d24 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
– None

Thread dump analysis

This is just some part of the whole dump. For dump analysis search for blocked thread by searching the word ‘BLOCKED’.

Here we have to look at 2 things

  1. Waiting to lock :  It means this thread is waiting to acquire lock on the given object which is currently acquired by some other thread
  2. Locked : It means this current thread has acquired the lock of the given object

If we see current dump, Thread-1 is ‘waiting to lock’ on object ‘<0x00000000d5d92248>’. If we search this object ‘Thread-0’ has already locked it.

Also Thread-0 is ‘waiting to lock’ on object ‘<0x00000000d5d92258>’ which is already acquired by Thread-1. So we can easily detect a deadlock here.

 

Using this technique we can analyse thread dumps and try to find blocking threads. Threads which are waiting to acquire lock on some object which is already occupied by some other thread which is not willing to leave it soon.

 

Uday Ogra

Connect with me at http://facebook.com/tendulkarogra and lets have some healthy discussion :)

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *