What is the difference between thread-safe Singleton Design Pattern with Double Check Locking as in the below code.
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (this) {
if(instance==null)
instance = new Singleton();
}
}
return instance;
}
}
And in below implementation other than Eager initialization.
public class Singleton {
private static volatile Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
The Double-Check Locking (DCL) idiom is an attempt to instantiate a singleton object in a lazy manner, where the singleton object is not created until the first time it is needed. The problem with this approach is that it is flawed and does not work. For an in-depth understanding of why this idiom will not work, see:
While Brian Goetz goes into great detail about the reason for idiom failing, for the sake of brevity, the problem can be summed up in the following paragraph:
In short, the Java Memory Model (JMM) does not guarantee that given two threads, one will not see a partially constructed instance of the
instancefield, since theinstancefield is observed outside of a synchronized block (i.e.,if (instance == null)).Note that as of JDK 5, the double-checked locking idiom is possible, but it is still delicate and should be avoided whenever another alternative can be used.
The reason developers attempted to create the DCL idiom in the first place is that use of the
synchronizedkeyword can result in a performance hit (according to Brian Goetz's article, as much as 100x).The second pattern is a much simpler approach to the singleton pattern since it makes the singleton object
static, which ensures that for all outside objects that attempt to access the singleton, only one object will ever be created. This approach is called eager instantiation because theinstanceobject is created prior to any outside object needing it. Eager instantiation will usually suffice unless there is major overhead in creating the singleton object.If lazy instantiation is required, a clever approach is to create a separate class with only the singleton instance as a
staticfield:Since
staticfields are not initialized in Java until the class is loaded by the classloader, theinstanceobject will not be instantiated until an outside object references theinstanceobject. Thus, we have achieved lazy instantiation through the compiler and Java runtime environment.