Initialization-on-demand holder idiom
In software engineering, the initialization-on-demand holder (design pattern) idiom is a lazy-loaded singleton. In all versions of Java, the idiom enables a safe, highly concurrent lazy initialization of static fields with good performance.[1][2]
public class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton instance() {
return Holder.INSTANCE;
}
}
The implementation of the idiom relies on the initialization phase of execution within the Java Virtual Machine (JVM) as specified by the Java Language Specification (JLS).[3] When the class Singleton is loaded by the JVM, the class goes through initialization. Since the class does not have any static variables to initialize, the initialization completes trivially. The static class definition Holder within it is not initialized until the JVM determines that Holder must be executed. The static class Holder is only executed when the static method instance() is invoked on the class Singleton, and the first time this happens the JVM will load and initialize the Holder class. The initialization of the Holder class results in static variable INSTANCE being initialized by executing the (private) constructor for the outer class Singleton. Since the class initialization phase is guaranteed by the JLS to be sequential, i.e., non-concurrent, no further synchronization is required in the static instance() method during loading and initialization. And since the initialization phase writes the static variable INSTANCE in a sequential operation, all subsequent concurrent invocations of the instance() will return the same correctly initialized INSTANCE without incurring any additional synchronization overhead.
Caveats
[edit source]While the implementation is an efficient thread-safe "singleton" cache without synchronization overhead, and better performing than uncontended synchronization,[4] the idiom can only be used when the construction of Singleton is guaranteed to not fail. In most JVM implementations, if construction of Singleton fails, subsequent attempts to initialize it from the same class loader will throw a java.lang.NoClassDefFoundError.
Another limitation is that it is impossible to pass parameters to the constructor of Singleton, as is called by the class loader.
See also
[edit source]External links
[edit source]References
[edit source]- ↑ The double checked locking idiom does not work correctly in Java versions prior to 1.5.
- ↑
INSTANCEshould be package private - ↑ See 12.4 of Java Language Specification for details.
- ↑ "Fastest Thread-safe Singleton in the JVM". literatejava.com.