Sunday 24 July 2016

Forever Singleton

What is Singleton? or What are singleton classes? or What is Singleton Design Pattern. These are one of the most common interview questions asked in Java as some experience level.There are various methods by which one can implement singleton class depending upon the requirement. The implementation is fairly simple yet a lot of complexity is involved while working with singleton classes, specially in multi-threaded environment.Following are some of the common ways of making a class singleton.

Eager Initialization


public class EagerInitialization
{
        private static volatile EagerInitialization singleInstance = new EagerInitialization();

        // private constructor
        private EagerInitialization()
       {
        }

        public static EagerInitialization getInstance()
    {
                return singleInstance;
        }
}

This is the most simple way of creating a singleton class.The singleInstance of class is a static variable and will be initialized only once, as soon as the class is loaded in to the memory.Notice the private constructor of the class, which will prevent any other class from making the object. The only way to get the object of the EagerInitialization class is to call the public getInstance() method of the class.
 Despite the simplicity of this method, it is not preferred. The major pitfall of this method is that Instance is created irrespective of it is requirement at runtime. Now, there might be a possibility that this heavy instance might go unused throughout the application. If you can sleep on that, then this is the best approach.

Lazy Initialization


public final class LazyInitializationSingleton
{
        private static volatile LazyInitializationSingleton lazyInstance = null;

      // private constructor
     private LazyInitializationSingleton()
     {
     }
     public static LazyInitializationSingleton getInstance()
    {
       if (lazyInstance == null)
          {
             synchronized (LazyInitializationSingleton.class)
             {
                 lazyInstance = new LazyInitializationSingleton();
              }
            }
            return lazyInstance;
      }
 }

There are 3 take aways from this.

1. It solved the problem of Eager Initialization, it the object will be created only when it is required for the first time
2.The lazyInstance of the class is made volatile so as to avoid any caching related issues.
3. The object creation is done inside the synchronized block.
In this, on first invocation the object will be created and the same object will be returned in subsequent invocations.Although at first, this method seems to solve all the problems but it has its own drawback in multi-threaded environment.
Suppose there are two Threads, T1 and T2, and both check for the null condition at the same time. Since the lazyInstance will be null for both, they both will assume that object needs to be created and will enter the synchronized block sequentially and will create the object.

DoubleCheckSingleton


public class DoubleCheckSingleton
{
  private static volatile DoubleCheckSingleton instance = null;

  // private constructor
  private DoubleCheckSingleton()
  {
  }

  public static DoubleCheckSingleton getInstance()
  {
    if (instance == null)
      {
      synchronized (DoubleCheckSingleton.class)
    {
        // Double check
        if (instance == null)
        {
          instance = new DoubleCheckSingleton();
        }
      }
    }
    return instance;
  }
}

This is the correct implementation of singleton class.Re checking the instance for null inside the synchronized block makes this class thread safe singleton.

Bill pugh solution

This is my personal favorite method of making a class singleton.It uses the concept of static block initialization with the advantage of Lazy Initialization.

public class BillPughSingleton
{
// private constructor
 private BillPughSingleton()
  {
  }
  private static class LazyHolder
  {
    private static final BillPughSingleton INSTANCE = new BillPughSingleton();
  }

  public static BillPughSingleton getInstance()
  {
    return LazyHolder.INSTANCE;
  }
}

As you can see, the static inner class will be loaded on the first invocation of getInstance method. And on subsequent invocations, the same object will be returned from the static inner class.

Using Enum


We use enum to create a single object of the class. Enum, as written in java docs, provide implicit support for thread safety and only one instance is guaranteed. This is also a good way to have singleton with minimum effort.

public enum EnumSingleton
{
  INSTANCE;
 
}

Now, based on your requirement you can choose which implementation of Singleton suits the purpose.



No comments:

Post a Comment