Wednesday 2 January 2013

Design Patterns- Singleton


Singleton Design Pattern:


Why?:


The intent of a singleton class is to ensure a class has only one instance, and provide a global point of access to it.

How?

  • Make the class of the single instance object responsible for creation, initialization, access, and enforcement.
  • Declare the instance as a private static data member.
  • Provide a public static member function that encapsulates all initialization code, and provides access to the instance
There are various approaches to achieve singleton behavior:


Eager initialization:- where an instance of a class is created much before it is actually required, in other words the instance is created at the startup only irrespective of whether any class requires it or not.


public class EagerSingleton{
private static volatile EagerSingleton instance = new EagerSingleton();
//private constructor
private EagerSingleton(){
}

public synchronized static EagerSingleton getInstance(){
if(null == instance){
instance = new EagerSingleton();
}
return instance;
}
}

Lazy Initialization:
means delaying the creation of object untill its first requested.

public final static LazySingleton{
private static volatile LazySingleton instance = null;
//Private constructor
private LazySingleton(){}
private LazySingleton getInstance(){
if(instance==null){
synchronized (LazySingleton.class){
instance = new LazySingleton();
}
}
return instance;
}
}
//There is a problem with this implementation, I am keeping it open for the discussion.
//why do we use volatile with instance variable?

The above method has some drawbacks, suppose there are Two threads T1 & T2 starts simultaneously and  both comes to create instance and execute if(instance == null), at this point of time they both will get instance to be null, they sequentially go into the synchronized block and create the instance. so this way you will end up with 2 instances of a singleton class :)

This can be solved by double check locking technique, where we recheck the instance variable in synchronized block.

public final static LazySingleton{
private static volatile LazySingleton instance = null;
//Private constructor
private LazySingleton(){}
private LazySingleton getInstance(){
  if(instance==null){
      synchronized (LazySingleton.class){
         if(instance==null){
             instance = new LazySingleton();
        }
    }
}
return instance;
}
}


Static Block Initialization:
As you now  the static blocks are executed during the class loading and even before a constructor is called, so using this feature we can achieve singleton for our class.
Lets see how?



public class StaticBlockSingleton {
      private static final StaticBlockSingleton instance;
      static{
                        try{
                                    instance = new StaticBlockSingleton ();
                        }
                        Catch(Exception e){
                                    Sysout(“Unexpected result!!!”);
                        }
            }
            private StaticBlockSingleton(){};
  public static StaticBlockSingleton getInstance(){
                        return instance;
            }

Above code has one drawback. Suppose there are 5 static fields in class and application code needs to access only 2 or 3, for which instance creation is not required at all. So, if we use this static initialization. we will have one instance created though we require it or not.


Adding readReslove():
So fare we have covered like, how to implement our singleton class, various issues and their resolutions.
Now there is could be one more situation, where you need to frequently serialize your singleton class. So while deSerialization, it creates a new object of a class.. OOOPPPPPSSSS…
Now how to solve this issue?
Well its pretty simple, you just need to add readResolve method in your implementation to override it to return the existing instance of you class.

Something like:
protected Object readReslove(){
            return instance;
}

clone():
So far so good, but there could be one more violation in singleton pattern.
If your class is implementing clonable interface then there is a possibility that you end up creating multiple objects of your singleton class.
To avoid this situation, you just simply override the clone of Object in your implementation of singleton to return the same instance or simply throw an exception from there saying CloneNotSupported Exception.
Like:
protected Object clone() throws CloneNotSupportedException
{
            //you can return the existing instance
            return instance;
           
            //or, you can throw an exception from here
            throw new CloneNotSupportedException(“Cloning not allowed for singleton classes”);



2 comments:

  1. volatile will pick up the latest value from main memory.it will not take values from thread memory.

    ReplyDelete
  2. •The classes java.lang.System and java.sql.DriverManager

    ReplyDelete