Sometime back I have written short article explaining Singleton Design Pattern. In which I’ve explained two ways to create Singleton pattern. Lazy Initialization and Runtime initialization.
The Singleton design pattern addresses all of the above concerns. With the Singleton design pattern you can:
- Ensure that only one instance of a class is created
- Provide a global point of access to the object
- Allow multiple instances in the future without affecting a singleton class’s clients
This simple example shows how to create Lazy Creation of Singleton ThreadSafe Instance without Using Synchronized Keyword. Another very interesting article you may want to take a look is Synchronized Fast Cache.
package crunchify.com.java.tutorials; /** * @author Crunchify.com * Problem Statement: Lazy Creation of Singleton ThreadSafe Instance without Using Synchronized Keyword */ public class Singleton { private Singleton() { } private static class HoldInstance { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return HoldInstance.INSTANCE; } }
The implementation relies on the well-specified initialization phase of execution within the Java Virtual Machine (JVM).
Another must read: Java: Producer Consumer Example – Handle Concurrent Read/Write
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 HoldInstance
within it is not initialized until the JVM determines that HoldInstance
must be executed.
The static class HoldInstance
is only executed when the static method getInstance
is invoked on the class Singleton
, and the first time this happens the JVM will load and initialize the HoldInstance
class.
The initialization of the HoldInstance
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 serial, i.e., non-concurrent, no further synchronization is required in the static getInstance
method during loading and initialization.
And since the initialization phase writes the static variable INSTANCE
in a serial operation, all subsequent concurrent invocations of the getInstance
will return the same correctly initialized INSTANCE
without incurring any additional synchronization overhead.
Use this pattern if the initialization of the class is expensive and it cannot be done safely at class-loading time and the initialization is concurrent. The crux of the pattern is the safe removal of the synchronization overhead associated with accessing a singleton instance.