Saturday, April 13, 2013

Simple deadlock example - jstack to the rescue

    The most popular deadlock example is about acquiring two different locks in the opposite order by two different threads. However it can be tricky to obtain deadlock in that way because we must encounter unlucky timings of the threads. I created a piece of code that is very likely to result in a deadlock.
Let's try:
public class DeadlockExample {
 public static void main(String[] args) throws InterruptedException {
  final Object o1 = new Object();
  final Object o2 = new Object();

  synchronized (o1) {
   new Thread(new Runnable() {
    @Override
    public void run() {
     synchronized (o2) {
      try {Thread.sleep(1000);} catch (InterruptedException ex){}
      synchronized (o1) {}
     }
    }
   }).start();
   Thread.sleep(1000);
   synchronized (o2) {}
  }
 }
}

After the execution the flow is totally hung. Let's look at the thread dump:
jstack PID

...
"Thread-0" prio=6 tid=0x000000000b6dc000 nid=0xfec waiting for monitor entry [0x
000000000d26e000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at test.DeadlockExample$1.run(DeadlockExample.java:18)
        - waiting to lock <0x00000007d5853cd8> (a java.lang.Object)
        - locked <0x00000007d5853ce8> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:722)...
"main" prio=6 tid=0x000000000025c800 nid=0x13b8 waiting for monitor entry [0x000
00000024bf000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at test.DeadlockExample.main(DeadlockExample.java:25)
        - waiting to lock <0x00000007d5853ce8> (a java.lang.Object)
        - locked <0x00000007d5853cd8> (a java.lang.Object)

Found one Java-level deadlock:
=============================
"Thread-0":
  waiting to lock monitor 0x0000000002125500 (object 0x00000007d5853cd8, a java.
lang.Object),
  which is held by "main"
"main":
  waiting to lock monitor 0x0000000002124000 (object 0x00000007d5853ce8, a java.
lang.Object),
  which is held by "Thread-0"

Java stack information for the threads listed above:
===================================================
"Thread-0":
        at test.DeadlockExample$1.run(DeadlockExample.java:18)
        - waiting to lock <0x00000007d5853cd8> (a java.lang.Object)
        - locked <0x00000007d5853ce8> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:722)
"main":
        at test.DeadlockExample.main(DeadlockExample.java:25)
        - waiting to lock <0x00000007d5853ce8> (a java.lang.Object)
        - locked <0x00000007d5853cd8> (a java.lang.Object)

Found 1 deadlock.
JStack (part of the regular JVM distribution) performs really well and it is able to enlist deadlocks for us. Thread dumps can also be obtained from VisualVM.

No comments :

Post a Comment