Cyber Guard
Fight against cyber crime

Singleton design pattern

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.

Singleton design pattern and dependency Injection
Singleton design pattern and dependency Injection

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
Multi-ton design vs Singleton Design (Eager Initialization) video

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

Singleton Design (Lazy Initialization) video

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
Refer this video to get more details of Thread Safe, Double-checked and Enum Singleton

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
Share

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *