Sunday, April 3, 2011

Singleton Design pattern with Java

Singleton Design pattern with Java

Singleton design pattern belongs to creational design pattern family. Singleton restricts instantiation of a class to one object.
Why singleton?
Share the single instance/ object among the application example:
1)      Connection pool
2)      Service Locator
3)      Configuration properties etc.
Principle: Instance of class is not possible without constructor.
If class does not have any constructor then compiler provides the default public constructor. If class contain at least one constructor at that time complier does not provide default constructor and used the appropriate constructor defined in a class as per the requirement to instantiate object of class.
Note: Define default constructor as private to restrict the initialization of class within same class.

Code Snippet 1:


Delay the instantiation of object until it’s required. The code snippet shows the object is not initialized until Singleton.getInstacne() method called.

package com.ashish.singleton;

public class Singleton
{
    //Declaring singleton field as static field
    //This field has static nature and will shared among all
    //instance of this class.
    private static Singleton singleton=null;
  
    //restrict object creation to this class only
    // Private access modifier play the critical role
    // to restrict the access of the constructor to the outsider.
    private Singleton()
    {
    }

    // Obtain instance of Singleton class with the help of
    // Singleton.getInstance() method.
    public static Singleton getInstance()
    {
        if(singleton ==null)
        {
            singleton=new Singleton();
        }
        return singleton;
    }
   
    // additional stuff ...
}

Restrict the cloning of singleton object by overriding the clone() method of object class
    /*
* Object.clone() is protected methods but it is safe to override and       *restrict the cloning explicitly.
     * Restrict the cloning by overriding clone method of the object class.
     */
    @Override
    protected Object clone() throws CloneNotSupportedException
    {
        throw new CloneNotSupportedException();
    }

Code snippet 2:


Initialize the singleton object as soon as class loader loads the class into the memory.

package com.ashish.singleton;

public  class Singleton
{
    //Singleton instance created by the class loader as soon as class
    // loaded into the memory
    private static Singleton singleton=new Singleton();
  
   
    //restrict object creation to this class only
    // Private access modifier play the critical role
    // to restrict the access of the constructor to the outsider.
    private Singleton()
    {
    }

    // This method just return the instance of class which is created at the
    // class loading time .
    // Singleton.getInstance() method.
    public static Singleton getInstance()
    {
         return singleton;
    }

    /// clone() method ....
    // additional stuff ...
}

Code snippet 3:


Initialize the singleton object as soon as class loader loads the class into the memory.

Code snippet 2 & 3 are identical but code snippet 3 uses static block to instantiate the singleton instance.


package com.ashish.singleton;

public  class Singleton
{
    //Declaring singleton field as static field
    //This field has static nature and will shared among all
    //instance of this class.
    private static Singleton singleton=null;
  
    static
    {
        // initialization of singleton field is handle by the
        // static block
        singleton=new Singleton();
    }
   
    //restrict object creation to this class only
    // Private access modifier play the critical role
    // to restrict the access of the constructor to the outsider.
    private Singleton()
    {
    }

    // Obtain instance of Singleton class with the help of
    // Singleton.getInstance() method.
    public static Singleton getInstance()
    {
         return singleton;
    }

    /// clone() method ....
    // additional stuff ...
}





Singleton design pattern and concurrency issues  


It is advisable to initialize the object only when it’s required. Delay initialization required additional consideration to ensure that integrity of the singleton is maintained even in concurrent access.
Note:  Java used the Monitor concept to implement mutual exclusion among the concurrent thread.

Code snippet 4:

The integrity of singleton object in multi-threaded environment can be sustain by declaring getInstance() as synchronize method.
package com.ashish.singleton;

public  class Singleton
{
    //Declaring singleton field as static field
    //This field has static nature and will shared among all
    //instance of this class.
    private static Singleton singleton=null;
        
    //restrict object creation to this class only
    // Private access modifier play the critical role
    // to restrict the access of the constructor to the outsider.
    private Singleton()
    {
    }

    // Obtain instance of Singleton class with the help of
    // Singleton.getInstance() method.
    public static synchronized Singleton getInstance()
    {
      if(singleton==null)
      {
            singleton=new Singleton();
      }
        return singleton;
    }

    /// clone() method ....
    // additional stuff ...
}

Key points
1)      Singleton object is thread safe
2)      Only one thread will execute the getInstance() method that will reduce the concurrency.
3)      Every time getInstance() method is called additional housekeeping task executed to achieve mutual exclusion among the thread…

Code snippet 5:


Optimize the concurrency by locking only those piece of code that need the mutual exclusion.

package com.ashish.singleton;

public class Singleton {
      // declaring singleton field as static field
      // this field has static nature and will shared among all
      // instance of this class.
      private static Singleton singleton = null;
     
// Sync lock to lock the object access.
      private static Object SYNC_LOCK = new Object();

      // restrict object creation to this class only
      // Private access modifier play the critical role
      // to restrict the access of the constructor to the outsider.
      private Singleton() {
      }

      // Obtain instance of Singleton class with the help of
      // Obtain instance of Singleton class with the help of
      // Singleton.getInstance() method.
      public static Singleton getInstance() {

            if (singleton == null) {
                  synchronized (SYNC_LOCK) {
                        if (singleton == null) {
                              singleton = new Singleton();
                        }
                  }
            }
            return singleton;
      }
      // / clone() method ....
      // additional stuff ...
}

Double null check required because
1)      if more than one thread concurrently check for the null check condition
2)      Only one thread at a time obtain the monitor to execute the critical section ( mutex section)
3)      Try to check any thread initializes the singleton object or not? If yes than avoid re-initialization of singleton object and access the existing object reference.

8 comments:

  1. To add to above based upon my understanding is

    1) If a class does dot have variables which holds up large amount of memory then instantiating through static block or static variable should not be a problem.
    And in this way you can do away with synchronize & performance(checking for null) overhead.

    one point which i observed & liked here is that singleton class should implement clone method in order to avoid creation of it's copy.

    ReplyDelete
  2. one more thing i want to ask is, what difference does it make of initializing an object in static block or during variable declaration time?

    ReplyDelete
  3. Hi Sarvajeet
    Static variables are class properties. This property associated with the class rather than instance of class.
    Singleton class does not contain all the field/variable as static, declaring rest of the fields/variable as instance variable and initialing lazily as and when required will improve the performance at the same time reduces amount of memory consume by the object .Hence there is no memory overhead issues even though initializing static reference when we declare the singleton field.
    If we eagerly instantiate the object then there is no need to synchronize initialization code block.
    OOPs Concept said that “Initialize object only when it’s required”
    A Class property (static variable) initializes with the default values once the class loader loads the class into the memory. Object reference initializes with null. When class loader inspect that static field not only declare but also initialize to specific value at that time default value is not assigned but the respective value are assigned to the reference. Static block executions take place once all static variable/field initialized into the memory.

    ReplyDelete
  4. nice blog .. a lot of information..
    http://kapilnevatia.blogspot.com/2011/03/singleton-pattern-in-java.html

    ReplyDelete
  5. ------------------------------------------------ linked in comments -----------------------------

    Abhishek Jain • it is specific to problem...

    ----------------------------------------------------------------------------------------------------

    Ashish Chudasama • yes , I have try to explain special consideration required while writing single threaded and multi-threaded application in terms of singleton design pattern.

    ----------------------------------------------------------------------------------------------------

    Ravi Barot • Nice information Ashish, But still Code Snipped 5 not resolved issues in multi thread env. Visit below link for going more depth in it.
    http://www.ibm.com/developerworks/java/library/j-dcl/index.html

    ----------------------------------------------------------------------------------------------------

    Chintan Shah • @Ravi, it works in the jdk 1.5!

    http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

    @Ashish double checked locking with volatile works in java 1.5 or later :)


    ----------------------------------------------------------------------------------------------------
    http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html


    // Works with acquire/release semantics for volatile
    // Broken under current semantics for volatile
    class Foo {
    private volatile Helper helper = null;
    public Helper getHelper() {
    if (helper == null) {
    synchronized(this) {
    if (helper == null)
    helper = new Helper();
    }
    }
    return helper;
    }
    }

    ReplyDelete
  6. Really a Good Post...may be you will like this also
    http://kapilnevatia.blogspot.com/2011/03/singleton-pattern-in-java.html

    ReplyDelete
  7. good. simple, straight to the point.

    ReplyDelete