Singleton Design Pattern


Singleton is a design pattern for object construction. It falls under the category of “creational” design patterns. As the name somewhat suggests, it enables us to have one and only one instance of a class. This class will be a singleton class.

In most cases, singleton objects are used to provide configuration settings or global environment to your application.

For example, when your application starts it initializes/constructs a global environment and populates it with client provided or default configuration parameters. These configuration settings may then be used by different components of your application as and when required. Here, it makes complete sense to make the “Environment” class a Singleton. Each time a component requires or queries the values of some configuration parameters, it need not create the instance of “Environment” class. It was created once during application startup and should be globally available in your application to other components that need to invoke its methods.

Another good example is “Logging” facility used by some applications. The “logging” mechanism provides the APIs to log debug messages, traces, errors etc. Just one instance of “Logging” class should be constructed and made available to the application. It will then act as a single access point to the complete “logging” infrastructure.

The “Runtime” class in JAVA also serves as a good example for a Singleton class.

Now coming to the implementation. A basic implementation would be:

class Singleton
{
    private static Singleton instance = NULL;

    private Singleton()
    {
       // do the required initialization
    }

    public static Singleton getInstance()
    {
      if(instance == NULL)
      instance = new Singleton();

      return instance;
    }
}

1. getInstance() is the method that will be used to construct and get the instance. Only the first call to this method will result in instance creation. Subsequent calls will get the existing instance.

2. The method needs to be static in order for the other components to invoke it without creating an object first, else the whole purpose of having a “singleton” class will be defeated. We can create/get instance as:

Singleton instance = Singleton.getInstance();

3. The “Singleton” class contains a private static member of its own type. This is the instance that will be created and used throughout the application. It needs to be static as it is used by the static function getInstance().

4. The constructor should be private in order to prevent any object creation by any other class. The only way to create an instance of this class is through “getInstance()” method, and it takes care of creating it only once.

The above implementation is not thread-safe. In a multi-threaded environment, we should make sure that multiple threads invoking the “getInstance()” method should not end up creating two different instances. This situation is actually possible owing to the scheduling and context-switching of threads by Operating System scheduler.

A straight forward way to tackle this in Java is to use “synchronized” keyword at method level. So, the thread-safe version of getInstance() method would be:

public static synchronized Singleton getInstance()
{
  if(instance == NULL)
  instance = new Singleton();

  return instance;
}

The above approach has a serious performance penalty associated with it. The “synchronized” keyword makes the entire method’s code mutex protected. So even after the instance is created(by the very first thread that gets to execute this method), subsequent invocations by multiple threads will still have to bear the lock/unlock cost associated with mutex or synchronization. This is something that we can avoid. Synchronization is required only when the instance is created. Remaining invocations of getInstance() are simply returning the created instance and there is really no critical section to be protected.

We can achieve this through block-level synchronization as follows:

public static Singleton getInstance()
{
   if(instance == NULL)
   {
     /* Threads T1 and T2 enter. T2 gets blocked 
      * and executes the critical section.
      */
     synchronized(Singleton.class)
     {
       instance = new Singleton();
     }
   }

   return instance;
}

Note that critical section is reduced and synchronization (mutex lock/unlock) will be used only when the object is created. Subsequent invocations by any number of threads will bypass the synchronized block and get the created instance.

Although we have addressed the performance problem, we have run into a serious correctness issue. Once T1 exits the critical section after creating the instance, thread T2 acquires the lock and enters the critical section, thus creating another instance — A Big Problem.

We use the “Double Locking” coding pattern to solve this problem. So here is the final thread-safe version of getInstance() method.

public static Singleton getInstance()
{
   if(instance == NULL)
   {
     /* Threads T1 and T2 enter. T2 gets blocked and 
      * T1 executes the critical section.
      */
     synchronized(Singleton.class)
     {
       if(instance == NULL)
         instance = new Singleton();
     }
   }

   return instance;
}

Now, once the second thread enters the critical section, it again checks whether the “instance” variable is NULL or not. Because thread T1 already created one, the variable won’t be NULL and thread T2 will simply exit after returning the instance.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: