Following is my singleton class where I am using double-checked-locking without using volatile keyword and without synchronizing the entire getInstance() method:
public class MySingleton {
private static MySingleton mySingleton;
public static MySingleton getInstance() {
if(mySingleton == null) {
synchronized(MySingleton.class) {
if(mySingleton == null) {
MySingleton temp = new MySingleton();
mySingleton = temp;
}
}
}
return mySingleton;
}
}
According to me, this is thread-safe. If anyone thinks, this is not thread-safe, can someone please elaborate on why he/she thinks this is not thread-safe? Thanks.
No. It does not.
Suppose some thread A calls
getInstance(), and ends up creating a new instance and assigning themySingletonvariable. Then thread T comes along, callsgetInstance()and sees thatmySingletonis notnull.At this point, thread
Thas not used any synchronization. Without synchronization, the Java Language Specification (JLS) does not require that thread T see the assignments made by thread A in the same order that thread A made them.Let's suppose that the singleton object has some member variables. Thread A obviously must have initialized those variables before it stored the reference into
mySingleton. But the JLS allows thread T to seemySingleton != nulland yet still see the member variables in their uninitialized state. On some multi-core platforms, it can actually happen that way.Assigning the object reference to a local
tempvariable first doesn't change anything. In fact, as Steve11235 pointed out, thetempvariable might not even actually exist in the byte codes or in the native instructions because either the Java compiler or the hot-spot compiler could completely optimize it away.