Are Java static initializers thread safe?

simon622 picture simon622 · May 18, 2009 · Viewed 47.9k times · Source

I'm using a static code block to initialize some controllers in a registry I have. My question is therefore, can I guarantee that this static code block will only absolutely be called once when the class is first loaded? I understand I cannot guarantee when this code block will be called, I'm guessing its when the Classloader first loads it. I realize I could synchronize on the class in the static code block, but my guess is this is actually what happens anyway?

Simple code example would be;

class FooRegistry {

    static {
        //this code must only ever be called once 
        addController(new FooControllerImpl());
    }

    private static void addController(IFooController controller) { 
        // ...
    }
}

or should I do this;

class FooRegistry {

    static {
        synchronized(FooRegistry.class) {
            addController(new FooControllerImpl());
        }
    }

    private static void addController(IFooController controller) {
        // ...
    }
}

Answer

Matthew Murdoch picture Matthew Murdoch · May 18, 2009

Yes, Java static initializers are thread safe (use your first option).

However, if you want to ensure that the code is executed exactly once you need to make sure that the class is only loaded by a single class-loader. Static initialization is performed once per class-loader.