Monday, September 2, 2013

Design Patterns - Singleton Pattern (Java)

Creational Patterns

Singleton Pattern

          A singleton pattern suggests that the implementing class does not want its instance to be created more than once (or restrict number of instances), thus making it restrictive constructor in order to avoid using ‘new’.
          In general, the singleton class has:
1.   Declares a member variable to store the class instance. 2.   Makes the visibility of default constructor for the class as ‘private’ 3.   Provides a public visibility method (generally named as ‘getInstance’), which takes care of providing the class instance.

Early instance creation vs lazy instance creation:
          In case, the class instance is created while loading the class through class loader, is known as early instantiation. In java, while declaring a member variable at class level, it can be declared as ‘static’ with initialized to the new instance of the owner class. This way, the class instance will be available at the time of application is started and classes  are loaded.
          singlInstance = new SingletonClass();singlInstance = new SingletonClass();
private SingletonClass() {}
          In this case, the ‘getInstance’ method, which needs to return the class instance would simply be:
                   public static SingletonClass getInstance(){
                             return singlInstance;
                   }

                   In case of the lazy initialization, the class member variable is declared as null and the actual class instance gets created when the ‘getInstance’ method invoked for the first time.
                   public static SingletonClass singlInstance = null;
                  
private SingletonClass() {}

public static SingletonClass getInstance(){
                             if (singlInstance == null) {
                                      singlInstance = new SingletonClass();
                             }                          
retutn singlInstance;
                   }
                  
          Making Instance Creation Thread Safe:
          To make the singleton class instance creation thread safe, there are 2 possible solutions:
<![if !supportLists]>1.   <![endif]>Create the instance of the class at the application class loading itself. This will make sure that the instance will be always available just when the application classes are loaded.
public static SingletonClass singlInstance = new SingletonClass();
So when any thread accesses the ‘getInstance’ of the class, the instance created early, will be always available and it will be returned, thus making no new creation of instance later.
<![if !supportLists]>2.   <![endif]>While with the lazy load, an instance created in ‘getInstance’ method will not be by default thread safe. To make it thread safe,
<![if !supportLists]>a.   <![endif]>Defining ‘getInstance’ method as synchronized
We can make the ‘getInstance’ method as synchronized, to make sure the first thread which gets the access, will make other threads wait. This will make sure that the instance will be created for the first time and other threads, once obtain the lock would use the same instance created in first thread.
public static synchronized SingletonClass getInstance(){
                             if (singlInstance == null) {
                                      singlInstance = new SingletonClass();
                             }                          
retutn singlInstance;
     }
<![if !supportLists]>b.   <![endif]>Making a synchronized block
The problem with synchronized method, is, it becomes overhead, once the first instance created. So every later call, which will only be getting the earlier created instance, needs to go in synchronized call. It is very much unnecessary and can be avoided using synchronized block in ‘getInstance’ method.
public static SingletonClass getInstance(){
                             if (singlInstance == null) {
                                      synchronized (SingletonClass.class) {
                                                singlInstance = new SingletonClass();
                                      }
                             }                          
retutn singlInstance;
     }
The above implementation would help in making sure that the synchronization will be applied only when the instance is not created, implying, all the calls post initialization, would go directly avoiding any cost of synchronization.
However, there is still an issue in the above implementation. The issue is mainly due to the fact that, if there are multiple threads trying to access ‘getInstance’ method simultaneously, when the instance is not yet created. In this case, all these threads will go in synchronized way, but, each one will end up in creating new instance.
<![if !supportLists]>                                                 i.    <![endif]>Avoiding faulty implementation
To avoid the fault, we need to make double check. The ‘double check’ would imply that, even if threads go in synchronized block as the instance is not created, but when they actually start the execution of the block, re-verify if the instance is still not created and then create it.
public static SingletonClass getInstance(){
                             if (singlInstance == null) {
                                      synchronized (SingletonClass.class) {
                                                if (singlInstance == null) {
                                                          singlInstance = new SingletonClass();
                                                }
                                      }
                             }                          
retutn singlInstance;
     }

Handle Cloning on the Singleton class
Cloning in java, allows by default shallow copy of an object. However, it is necessary that to have the class implementing the ‘Clonable’ interface, if it needs to clone in later stage.
In the above example, even if the user tries to get the clone on the SingletonClass instance, the java program will end up in throwing java.lang.CloneNotSupportedException.
In order to support coning in singleton, would mean allowing coning, without creating any new instance if already created.
In this case, we will need to implement ‘Clonable’ interface for our Singleton class.
public class SingletonClass implements Cloneable

and also, override the clone() method
          private Object Clone(){
                   return SingletonInstance;
          }


Avoid allowing the Singleton class extensible
 To make sure your singleton class will not be extended and used explicitly, you can make it ‘final’ class. (Note: By making the constructor ‘private’, would mean, the extensibility is also avoided. However, it is a best practice to make a class final, if you know it should not be extended)

Handle Serialization on Singleton Class
 Serialization in java will allow storing the state of the object. The state can be saved in a file. The stored state can be read using de-Serialization.
By default, if anyone tries to serialize the singleton class object, it will throw java.io.NotSerializableException   
In case if we need to make sure the singleton class state can be stored and used in case it is crashed, we may want to use serialization.
To allow the singleton class supports serialization, there are few changes will be needed. These changes are important in order to keep the singleton class not allow having multiple instances.
Below are the changes we need to make:
<![if !supportLists]>·         <![endif]>Implement the readObject method in your singleton class. And make sure to return only the existing  instance.
<![if !supportLists]>·         <![endif]>Here is the sample implementation:
private void readObject (ObjectInputStream oInstream) throws IOException, ClassNotFoundException {
                   oInstream.defaultReadObject();
                   if (SingletonInstance == null){
                             synchronized (SingletonClass.class) {
                                      if (SingletonInstance == null){
                                                SingletonInstance = this;
                                      }
                             }
                   }
          }
         
          private Object readResolve() throws ObjectStreamException {
        return SingletonInstance;
    }