I came across a deadlock scenario which can be summarized as the StaticDeadlock class shown below.
This simple program will freeze at o.getClass(). Here’s my speculation of what happened, but can someone explain it better?
1) the program enters StaticDeadlock static block
2) thread starts
3) main thread is put in wait for thread to finish, hence can’t finish the static block
4) inside thread it access StaticDeadlock.o but StaticDeadlock’s static block is not finished yet. Hence the program freezes?
public class StaticDeadlock
{
private static final Object o = new Object();
static {
MyThread thread = new MyThread();
thread.start();
try {
thread.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main (String[] args)
{
System.out.println("all is well.");
}
static class MyThread extends Thread
{
@Override
public void run ()
{
System.out.println("inside mythread");
o.getClass();
}
}
}
Yes, that’s pretty much it. The new thread is waiting for the class initializer of
StaticDeadlockto complete before it accesses the static member. See section 12.4.2 of the Java Language Specification for more details, in particular these steps:It won’t even get past step 1 in the second thread, as the first thread has the lock and won’t release it.
Note that it’s not calling
getClass()which causes the problem – doing anything which requires the value ofowill make the second thread wait until the class initializer has completed, which of course won’t happen because the first thread is waiting for the second thread to finish.