Saturday, 9 December 2017

Singleton Design Pattern, a complete guide

In this blog, we are going to discuss all about Singleton Design Pattern which is one of the popular topic during Java Interview.

You can see a lot of discussion on this topic on various  blogs or sites in google but what I personally feel none of them have covered the entire design. So here I am going to share the complete design step by step.

What is Singleton pattern?

Singleton pattern ensures that class has only one instance and it provides a global point to access it.
Real time example of Singleton pattern is JDBC  getConnection() method.
Below one is the sample implementation of Singleton class:

public class SingleTon {
private static SingleTon singletonObj;
//constructor should be always private ,else somebody can easily     //creates its object.
private SingleTon()
{

}
public static SingleTon getInstance()
{
if(singletonObj==null)
singletonObj=new SingleTon();

return singletonObj;

}

}


/****End of code****/


So here we have created the Singleton class which restricts creation object using new operator as we made the constructor as private. So we have ensured that at any point time there would be only one instance of Singleton Class. We can write the code in main() method as below:

public static void main(String args[]){
  SingleTon singleton=SingleTon.getInstance();
}

Congratulation!!! We have created the SingleTon instance which can be accessed globally.

Wait!!!!!, this code can be cracked using Reflection in java that means even though we made Constructor as private but still during run time any body can create its instance using Reflection, here is the code snippet.

public class SingleTontest {

public static void main(String[] args) throws                               InstantiationException, IllegalAccessException,                     IllegalArgumentException, InvocationTargetException {

 /**
  * getDeclaredConstructors() method returns the number of            *   constructor present in the class,
  * default constructor always comes in 0th index 
  */
Constructor[] cons =                                                 SingleTon.class.getDeclaredConstructors();
cons [0].setAccessible(true); 

// get the instance of the class, initially it was                   // null,


SingleTon s2=(SingleTon)cons[0].newInstance();


System.out.println("hashcode after creating new                             Intance--> "+s2.getInstance().hashCode());


// get all the declared fields, in our class we                     // have only one declared field as singletonObj


Field [] f1=s2.getClass().getDeclaredFields();


f1[0].setAccessible(true);


//setting the singletonObj as NULL during runtime                   //using Reflection


f1[0].set(f1[0].getName(), null);


System.out.println("after setting null to                             singletonObj--> "+s2.getInstance().hashCode()); 


   }


}


Output:

hashcode after creating new Intance--> 366712642

after setting null to singletonObj--> 1311053135


So here we can conclude that using reflection we can create a new instance even though contructor is private and we can change its state to null as well.


So the Question here is how we can come out of this problem. Here is the solution, we have to throw UnsupportedOperationException() from the constructor which can ensure if anybody try to create an instance, it will throw this exception.

Code Snippet:

public class SingleTon {
private static SingleTon singletonObj;
//constructor should be always private, else somebody can //easily creates its object.

private SingleTon()
{
     throw new UnsupportedOperationException();
}

public static  SingleTon getInstance()
{
if(singletonObj==null)
singletonObj=new SingleTon();

return singletonObj;

}


}


But We are not yet done!!, what will happen if multiple threads like Thread 1, Thread 2, Thread 3 will try access getInstance() method, will it creates three different singletonObj for three threads, well quite possible as per our above class design.

To resolve this issue, we should use synchronized keyword to make the getInstance method as Thread safe which ensures, at a time only one thread will be executed.

Lets imagine the scenario like Thread 1 access the getInstance() method so Thread 2 and Thread 3 will have to wait unless Thread 1 come out of getInstance() method. Next time when Thread2 or Thread 3 will access the getInstance() method, it will see that singleton instance has already been created so they wont create any other singleTon object. 

Well but it will impact the performance because every thread has to wait at the method level, to resolve this issue, we can synchronized only the condition where it check the instance value, which can improve the performance.

Here is the complete Singleton class:

public class SingleTon {
private static SingleTon singletonObj;
//constructor should be always private ,else                //somebody can easily creates its object.
private SingleTon()
{
throw new UnsupportedOperationException();
}
public static  SingleTon getInstance()
{

if(singletonObj==null)
synchronized (SingleTon.class) {
if(singletonObj==null)
singletonObj=new                                                    SingleTon();
}

return singletonObj;

}

}


/***************End of SingleTon design pattern**************/


You may also Like:

Design your custom or own HashMap implementation in JAVA







No comments:

Post a Comment

Use of Lamda Expression and Functional Interface in JAVA 8

In this blog, we are going to discuss one of the most important features of JAVA 8 which is Lamda Expression and Functional Interface. A...