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:
getInstance()
for the first time so that mc is initialized.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?
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.