Thursday, November 20, 2014

Singleton Design Pattern

Singleton Design Pattern is one of the simplest but the trickiest of all design patterns. It falls under Creational Pattern. During interview lots of cross questions can be asked by the interviewer which can be very tricky to answer if you do not know them. In this blog i will cover all of them. I will start with the simplest and move towards the complicated one.

But before we move on lets have a shot introduction of Singleton Pattern. As we all know a Singleton Pattern helps us in situation where we want to have just one instance of class in our application at any given point of time. This is achieved by declaring the constructor of the class as private so that the outside world can not create the instance of our singleton class and provide a factory method like get instance to create the instance of the class.

Lets see this through code demonstration:-

package com.sanjiv.designpatterns.singleton;

public class MySingleton {

private static MySingleton INSTANCE = null;

private MySingleton(){
}


public static MySingleton getInstance(){

if(INSTANCE == null){
INSTANCE = new MySingleton();
}

return INSTANCE;
}

}

The above code works fine if we are working in a single threaded environment but breaks in a multi-threaded environment as two threads can at a time call the getInstance() method and they both find that the INSTANCE variable is null and both thread end up creating instance of a singleton class. So the above code might break in a multi-threaded environment.

The easiest solution to make the singleton thread-safe is use Eager Initialization.

package com.sanjiv.designpatterns.singleton;

public class EagerlyInitializedSignleton {

private static final EagerlyInitializedSignleton instance = new EagerlyInitializedSignleton();

//make the constructor private
private EagerlyInitializedSignleton(){

}



public static EagerlyInitializedSignleton getInstance(){

return instance;

}
 If your singleton class is not using a lot of resources, this is the approach to use. But in most of the scenarios Singleton classes are created for resources such as File System,  Database connections etc and we should avoid the instantiation until unless  client calls the getInstance method. Also this approach doesn’t provide any options for exception handling.

The first approach that we used in the begining to demonstrate Singleton Pattern uses Lazy Initializaion but its not thread safe. So lets try to make that thread safe. One way to do that is to make the getInstance method thread safe by using the synchronized key work as below:-

public static synchronized ThreadSafeSingleton getInstance(){

if(instance == null){
instance = new ThreadSafeSingleton();
}

return instance;
}


The above code works fine in a multithreaded environment but comes with some performance penalty. The only realistic time when the threads need to synchronize is for the first time, once the instance is created there is not need to synchronize. So this isnt the best of the approaches to create a singleton in a multi-threaded environment.

To overcome this situation the double checking mechanism can be used. Lets see this through code demonstration:-

public static ThreadSafeSingleton getInstanceUsingDoubleChecking(){

if(instance == null){
synchronized (ThreadSafeSingleton.class) {
if(instance == null){
instance = new ThreadSafeSingleton();
}

}
}

return instance;
}

This seems a better way to create a singleton class in a multi-threaded environment. But this also has some limitation. Like suppose your singleton class uses serializable interface. So when a serilaizable singleton class is de-serialized we will end up having two instances of the same class. To avoid this we can write our own implementation of the readResolve() method and can call the getInstance() method from within.


protected Object readResolve() {
   return getInstance();
}

We can still clone() the class and create more than one instance of it. If the interviewer asks, tell that for a class to be clonable it has to implement clonable interface. Now he says that our class implements clonable interface then how will you ensure that we dont have multiple instance of the singleton. The best way to do that is to throw CloneNotSupported exception from the clone method. This way you can restrict your clients from creating more than one instance by cloning the object.


protected final Object clone() throws CloneNotSupportedException{


throw new CloneNotSupportedException();


}


But still the Singleton Class can have multiple instance by using java reflection API. We can create more than one instance on the fly by using Reflection.Well the solution to all the problems(seriliazble,clonable and reflection) is to use Enum to carate a singleton. Its the easiest and safest way to create a singleton.

public enum SingletonEnum{

INSTANCE


}

It is as simple as that and saves you from a lot of headache.

Bill Pugh came up with his solution of implementing a Singleton. This is also worth to have a look. He came up with the idea of using inner static class to create a singleton.

public class BillPughSingleton {

private BillPughSingleton(){}

private static class SingletonHelper{

private static final BillPughSingleton instance = new BillPughSingleton();
}

public static BillPughSingleton getInstance(){

return SingletonHelper.instance;
}
}


Please leave your comments and suggestions.

Thanks for reading.










No comments:

Post a Comment