Search code examples
javamultithreadingsingletondouble-checked-locking

Threadsafe Singleton without synchronization in Java?


I have a multithreaded application and a singleton class:

public final class Singleton {

    private static MyClass mc;

    public static final Object getInstance() {
            if(mc == null) {
                mc = new MyClass();
            }
            return mc;
    }

}

Of course, this will not work in a general multithreaded scenario. But consider the following scenario:

  • In the beginning there is only one thread
  • This one thread calls getInstance() for the first time so that mc is initialized.
  • After that all other threads are started by the first thread.

My assumption:

This should work because the initialization of the mc field and the object's construction happen-before all subsequent Thread.start() calls that start the other threads. And the Thread.start() for a thread happens-before all other actions of that thread. It follows that the initialization of mc happens-before all actions in all other threads so that getInstance() will return the right value for all threads.

Is this assumption right? Why / Why not?


Solution

  • Your analysis is indeed perfectly fine.

    To be precise: Everything that happens on one thread sequentially has a happens before relationship (obviously, the says it this way: "If x and y are actions of the same thread and x comes before y in program order, then hb(x, y)." )

    17.4.5 of the JLS then goes on to say the following:

    "A call to start() on a thread happens-before any actions in the started thread."

    So taken together there's a clear happens before order between the singleton instantiation and the started threads, hence they're guaranteed to see the up to date value.

    Simply said: A created thread is guaranteed to see everything its parent did before it was created, otherwise concurrent programming would be nigh impossible.