Singleton

Singleton is a part of Gang of Four design pattern and it is categorized under creational design patterns. In this article, we are going to take a deeper look into the usage of the Singleton pattern. It is one of the most simple design patterns in terms of the modelling but on the other hand, this is one of the most controversial patterns in terms of complexity of usage.
Singleton pattern is a design pattern which restricts a class to instantiate its multiple objects. It is nothing but a way of defining a class. Class is defined in such a way that only one instance of the class is created in the complete execution of a program or project. It is used where only a single instance of a class is required to control the action throughout the execution. A singleton class shouldn’t have multiple instances in any case and at any cost. Singleton classes are used for logging, driver objects, caching and thread pool, database connections.
The singleton pattern is one of the simplest design patterns. Sometimes we need to have only one instance of our class for example a single DB connection shared by multiple objects as creating a separate DB connection for every object may be costly. Similarly, there can be a single configuration manager or error manager in an application that handles all problems instead of creating multiple managers.
The singleton pattern is a design pattern that restricts the instantiation of a class to one object.
Let’s see various design options for implementing such a class. If you have a good handle on static class variables and access modifiers this should not be a difficult task.
An implementation of singleton class should have following properties:
  1. It should have only one instance : This is done by providing an instance of the class from within the class. Outer classes or subclasses should be prevented to create the instance. This is done by making the constructor private in java so that no class can access the constructor and hence cannot instantiate it.
  2. Instance should be globally accessible : Instance of singleton class should be globally accessible so that each class can use it. In Java, it is done by making the access-specifier of instance public.
Type 1 -- Classical Java implementation of singleton design pattern
class Singleton
{
    private static Singleton obj;
    // private constructor to force use of getInstance() to create Singleton object
    private Singleton() {}
  
    public static Singleton getInstance()
    {
        if (obj==null)
            obj = new Singleton();
        return obj;
    }
}

Here we have declared getInstance() static so that we can call it without instantiating the class. The first time getInstance() is called it creates a new singleton object and after that it just returns the same object. Note that Singleton obj is not created until we need it and call getInstance() method. This is called lazy instantiation.The main problem with  this is that it is not thread safe.
Type 2 -- Thread Synchronized Java implementation of singleton design pattern using get Instance()
class Singleton
{
    private static Singleton obj;
    private Singleton() {}
    public static synchronized Singleton getInstance()
    {
        if (obj==null)
            obj = new Singleton();
        return obj;
    }
}

Here using synchronized makes sure that only one thread at a time can execute getInstance().
The main disadvantage of this is method is that using synchronized every time while creating the singleton object is expensive and may decrease the performance of your program. However if performance of getInstance() is not critical for your application this method provides a clean and simple solution.

Type 3 : Eager Instantiation-- Static initializer based Java implementation of singleton design pattern
class Singleton
{
    private static Singleton obj = new Singleton();
    private Singleton() {}
    public static Singleton getInstance()
    {
        return obj;
    }
}


Here we have created instance of singleton in static initializer. JVM executes static initializer when the class is loaded and hence this is guaranteed to be thread safe. Use this method only when your singleton class is light and is used throughout the execution of your program.

If you notice carefully once an object is created synchronization is no longer useful because now obj will not be null and any sequence of operations will lead to consistent results.
So we will only acquire lock on the getInstance() once, when the obj is null. This way we only synchronize the first way through, just what we want.
Type 4 : Double Checked Locking based Java implementation of singleton design pattern
class Singleton
{
    private volatile static Singleton obj;   
    private Singleton() {}
    public static Singleton getInstance()
    {
        if (obj == null)
        {
            // To make thread safe
            synchronized (Singleton.class)
            {
                if (obj==null)
                    obj = new Singleton();
            }
        }
        return obj;
    }
}

We have declared the obj volatile which ensures that multiple threads offer the obj variable correctly when it is being initialized to Singleton instance. This method drastically reduces the overhead of calling the synchronized method every time.

  • Singleton classes can have only one instance and that instance should be globally accessible.
  • java.lang.Runtime and java.awt.Desktop are 2 singleton classes provided by JVM.
  • Singleton Design pattern is a type of creational design pattern.
  • Outer classes should be prevented to create instance of singleton class.
  • Default scope of Spring is Singleton