Saturday, March 26, 2011

Singleton Pattern



The Java Singleton pattern belongs to the family of design patterns that governs the instantiation process.
Singleton Pattern ensures a class has only one instance and provides a global point of access to it.
The default constructor of the class is made private, which prevents the direct instantiation of the object by other classes. 

A static modifier is applied to the instance method that returns the object as it then makes this method a class level method that can be accessed without creating an object.
You implement the pattern by creating a class with a method that creates a new instance of the class if one does not exist. If an instance of the class exists, it simply returns a reference to that object.
                                                 
How the Singleton pattern works
Here’s a typical example of Singleton:

               public class Singleton {
               private static Singleton INSTANCE = null;
               /*
                * Private constructor suppresses generation of default constructor and
                * Instance creation from outside the class.
                */
               private Singleton() {
               }
               public static Singleton getInstance() {
                               if (INSTANCE == null) {
                                              INSTANCE = new Singleton();
                               }
                               return INSTANCE;
               }
}


The Singleton class’s constructor is made private, which prevents the direct instantiation of the object by other classes using the new keyword. A static modifier is applied to the instance method that returns the Singleton object; it makes this a class level method that can be accessed without creating an object.


Lets checkout potential problems in the above example:

(Single ready to mingle)
Although the Singleton design pattern is one of the simplest design patterns, it has a number of pitfalls.

1.    Multithreaded Environment
2.    Cloning
3.    Serialization
4.    Sub classing

Risks for multi-threaded applications:
It could happen that the getInstance() may be called twice from 2 different classes at the same time and hence more than one object being created. This could violate the design patter principle. 

 
In order to prevent the simultaneous invocation of the getInstance() by 2 threads or classes simultaneously we add the synchronized keyword to the method declaration.

               public static synchronized Singleton getInstance(){}
This is a thread-safe version of a Singleton

The other way to prevent this is do an eager instantiation of the instance rather than a lazy instantiation.
Instead of synchronizing the whole method you can also make the instance variable as static final. It is thread-safe because static member variables created when declared are guaranteed to be created the first time they are accessed. You get a thread-safe implementation that automatically employs lazy instantiation.   
               private static final Singleton INSTANCE = new Singleton();

Think to prevent cloning:


We will be able to create a copy of the Object by cloning it using the Object’s clone method.. To avoid this, you need to override the Object’s clone method, which throws a CloneNotSupportedException exception:

      public Object clone() throws CloneNotSupportedException {
         throw new CloneNotSupportedException();
       }

Avoiding multiple instances due to Serialization:
 If Singleton Class implements the Serializable interface, then  instances can be serialized and deserialized. However, if you serialize a singleton object and subsequently deserialize that object more than once, you will have multiple singleton instances.
To avoid the above you need to implement readResolve() method.
     private Object readResolve() {
               return INSTANCE;
               }

This singleton implementation returns the alone singleton instance from the readResolve() method;
Therefore, whenever the Singleton class is deserialized, it will return the same singleton instance. 
Avoiding multiple instances due to Subclassing:
We may want to make the Singleton class final to avoid sub classing of Singletons that may cause other problems.
Conclusion:
We can use Singleton pattern while creating objects of thread pools, caches etc to avoid wasting resources. The Singleton pattern is widely used and has proved its usability in designing software. Although the pattern is not specific to Java, it has become a classic in Java programming. Despite its simplicity, we must remember the limitations of the Singleton pattern that are described in this article.