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.

Leave a Comment