Program hangs if thread is created in static initializer block Program hangs if thread is created in static initializer block multithreading multithreading

Program hangs if thread is created in static initializer block


You're not just starting another thread - you're joining on it. That new thread has to wait for StaticInitializer to be fully initialized before it can proceed, because it's trying to set the state field... and initialization is already in progress, so it waits. However, it's going to be waiting forever, because that initialization is waiting for that new thread to terminate. Classic deadlock.

See the Java Language Specification section 12.4.2 for details about what's involved in class initialization. Importantly, the initializing thread will "own" the monitor for StaticInitializer.class, but the new thread will be waiting to acquire that monitor.

In other words, your code is a bit like this non-initializer code (exception handling elided).

final Object foo = new Object();synchronized (foo){    Thread t1 = new Thread(new Runnable() {        @Override        public void run() {            synchronized (foo) {                System.out.println("In the new thread!");            }        });    t1.start();    t1.join();});

If you can understand why that code would deadlock, it's basically the same for your code.

The moral is not to do much work in static initializers.


classloading is kind of a sensitive time in the jvm. when classes are being initialized, they hold an internal jvm lock which will pause any other thread trying to work with the same class. so, your spawned thread is most likely waiting for the StaticInitializer class to be fully initialized before proceeding. however, your StaticInitializer class is waiting for the thread to complete before being fully initialized. thus, deadlock.

of course, if you are truly trying to do something like this, the secondary thread is superfluous since you are joining it right after you start it (so you might as well just execute that code directly).

UPDATE:

my guess as to why the deadlock is not detected is because it is occurring at a much lower level than the level at which the standard deadlock detection code works. that code works with normal object locking, whereas this is deep jvm internal stuff.


I was able to get your program to run by commenting out the line state = 11;

You can not set state=11 until you have completed initialization. You can not complete initialization until t1 finishes running. T1 can not finish running until you set state=11. Deadlock.