What is Singleton design pattern ?
When there is a need of creating only one object of a class in the entire life of a software, then we use Singleton design pattern. In Object oriented programming paradigm, Object is the instance of a class. Class is the blueprint of object. There are certain point of requirement where developers are allowed to create only one instance of the class. Such type of task might be required to initialise resources to the application .The run time injects the object into different parts of application without creating 2nd object.

Can find more definition here from wiki .
For Eg: DataBase properties needs to be initialised only once during execution of the application.
Types of Singleton design pattern
- Eager Initialization
- Lazy initialization
- Thread-Safe
- Double-Checked
- Enum Singleton
How to achieve Singleton design pattern ?
1)Singleton design pattern – Eager Initialization
Create a class with a private constructor. Declare a private static variable of the same class and initialise the class by using the constructor. Create a static method which will return instance of the same class which is created before.
Whenever , there is a need to get the instance of the class then call the static method to get the instance.
Priner.java
package singleton; public class Printer { public static void main(String[] args) { Driver dr=Driver.getInstance(); dr.print("First Doc"); } } //Singleton class class Driver { private static Driver driver=new Driver(); private Driver() { System.out.println(" Driver's object got created "); } public static Driver getInstance() { return driver; } public void print(String doc) { System.out.println("Print is going on for "+doc); } }
output
Driver's object got created Print is going on for First Doc
Full Source code
Click to download above source
2) Singleton design pattern -Lazy Initialization
Cons of the eager initialization
In eager initialization, the instance of the class get created even there is no need of the instance. Eager initialized singleton instance gets created during class loading process.
In lazy Intialization, the instance of the class get created only at the time of requirement. The class loader does not create instance of the singleton class. The singleton object get created through a method. A static method in singleton class creates object of the class by using new keyword and returns the same to the caller.
The static method also ensures for not creating multiple object by comparing null with the object. If the object contains null then the method creates the object else the method only returns the not-null object to the caller.
Printer.java
package singleton; public class Printer { public static void main(String[] args) { Driver dr=Driver.getInstance(); Driver dr1=Driver.getInstance(); dr.print("First Doc"); dr1.print("Second Doc"); } } //Singleton class using Lazy initialization class Driver { public static Driver driver=null; private Driver() { System.out.println(" Driver's object got created "); } public static Driver getInstance() { if(driver==null) { driver=new Driver(); } return driver; } public void print(String doc) { System.out.println("Print is going on for "+doc); } }
In the above code the method getInstance(..) checks the value of “driver” variable with null to ensure creation of only one object of “Driver” class.
Even the caller calls getInstance(..) twice , the method creates only one object. The constructor gets called only once, but the print(..) method gets called twice.
Output
Driver's object got created Print is going on for First Doc Print is going on for Second Doc
Full Source code
Click to download above source
3) Singleton design pattern – Thread-Safe
In eager intialization or lazy initialization singleton model, the instance of singleton class gets created by one thread i.e main thread. But when there will be multiple thread to access object of singleton object then run time environment creates different object for different thread. This goes against the rule of singleton design pattern. Hence, programmer needs to make the singleton object creation thread safe.
Thread safe Singleton design pattern can be achieved by using synchronization. Synchronized method can be accessed by only one thread at a time. If multiple thread try to access thread safe or synchronized method then run time environment makes other threads wait till one thread is not finished working on synchronized method.
Thread safe model is nothing but lazy initialization + synchronization
Let us look at an example.
Printer.java
package singleton; public class Printer { public static void main(String[] args) { Thread th1=new Thread(new Runnable() { @Override public void run() { Driver dr=Driver.getInstance(); dr.print("First Doc"); } }); Thread th2=new Thread(new Runnable() { @Override public void run() { Driver dr1=Driver.getInstance(); dr1.print("Second Doc"); } }); th1.start(); th2.start(); } } //Singleton class using Thread safe initialization class Driver { public static Driver driver=null; private Driver() { System.out.println(" Driver's object got created "); } public static synchronized Driver getInstance() { if(driver==null) { driver=new Driver(); } return driver; } public void print(String doc) { System.out.println("Print is going on for "+doc); } }
Output
Driver's object got created Print is going on for First Doc Print is going on for Second Doc
Note: If synchronized keyword will not be used with
getInstance() method then there will be multiple object of class Printer and output will be following. Which is wrong in the context of singleton model.
Wrong output (multi-ton object) without thread-safe
Driver's object got created Print is going on for Second Doc Driver's object got created Print is going on for First Doc
Full source code download
Click to download above source
4) Singleton design pattern – Double-Checked
In thread safe singleton design, the synchronized method gets totally inaccessible by other thread in case of a thread is working on it.
Sometime , the synchronized might be doing some task which need not to be thread safe. Making the object creation part thread safe will satisfy the requirement of implementing singleton model in multithreaded environment. This can be done by using synchronized block inside the method which creates object of singleton class.
Double check single ton model is combination lazy initialization + synchronized block.
Let us have a look at the sample code.
Printer.java
package singleton; public class Printer { public static void main(String[] args) { Thread th1=new Thread(new Runnable() { @Override public void run() { Driver dr=Driver.getInstance(); dr.print("First Doc"); } }); Thread th2=new Thread(new Runnable() { @Override public void run() { Driver dr1=Driver.getInstance(); dr1.print("Second Doc"); } }); th1.start(); th2.start(); } } //Singleton class using double-check class Driver { public static Driver driver=null; private Driver() { System.out.println(" Driver's object got created "); } public static Driver getInstance() { System.out.println("Non sunchronized line1"); synchronized(Driver.class) { if(driver==null) { driver=new Driver(); } } System.out.println("Non sunchronized line2"); return driver; } public void print(String doc) { System.out.println("Print is going on for "+doc); } }
Note: In the above code the lines present inside getInstance() but outside synchronized block are accessible by multiple thread simultaneously.
Output
Non sunchronized line1 Non sunchronized line1 Driver's object got created Non sunchronized line2 Non sunchronized line2 Print is going on for Second Doc Print is going on for First Doc
Full source code download
Click to download above source
5) Singleton design pattern – Enum Singleton
An object of any class can be serialized to get stored in a permanent or persistent storage like file or database. This can be done by using writeObject() in Java’s IO operation. The saved serialized object can be read (known as deserialization) for future use. This can be done by readObject() in Java’s IO operation.
But, written serialized object and fetched deserialized object will be have different hashcode. Different hashcode means different objects. So serialization and deserialization does not support singleton design pattern. Java’s reflection mechanism allows access private constructor from outside of the class. This makes the violation of singleton model.
An Enum can not serialized it’s state into persistent storage. The variables inside Enum behave like transient variable in any serialized class.
In Enum singleton model, the write and read objects are identical .
Printer.java
package singleton; public class Printer { public static void main(String[] args) { Driver dr1=Driver.myDriverInstance; Driver dr2=Driver.myDriverInstance; dr1.print("First Doc"); dr2.print("Second Doc"); } } //Singleton using enum enum Driver { myDriverInstance; public void print(String doc) { System.out.println("Print is going on for "+doc); } }
output
Print is going on for First Doc Print is going on for Second Doc
Full source code download
Click to download above source
Reflection can break Singleton design
Printer.java
package singleton; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Printer { public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { //Violation of Singleton model by creating multiple object Driver dr1 = Driver.myDriverInstance; Constructor<Driver> constructor = (Constructor<Driver>) dr1.getClass().getDeclaredConstructor(new Class[0]); constructor.setAccessible(true); Driver dr2 = (Driver) constructor.newInstance(); if(dr1 !=dr2) System.out.println("Objects are different"); else System.out.println("Objects are same"); } } //Singleton Class with private method class Driver { public static Driver myDriverInstance=new Driver(); private Driver() { System.out.println("Driver object got created"); } public void print(String doc) { System.out.println("Print is going on for "+doc); } }
Output with violation of Singleton Design
Driver object got created Driver object got created Objects are different