Singleton design pattern

You must have heard about the Singleton Design Pattern in Java. One of the most common question in Interviews. So here I will discuss Singleton pattern and try to resolve all queries you might have for Singleton pattern.

What is Singleton Design Pattern

If you are in Java then you must have used the new keyword. This new keyword creates an Object of class whenever required. But there are some scenarios where you don’t want to create individual Object for a different purpose. Singleton Pattern ensures that one and only one Object is instantiated for a given class. Whenever an object of a given class is required, only single(No more than one object) Object get returned.

Implementation of Singleton Design Pattern

Now you know what is the Singleton Design Pattern. Next step would be to implement it. There are different ways you can implement Singleton. Before you start implementation, you need to understand what are the different ways to create an Object.

Different Ways to create an Object

  • new Keyword
  • Using the New Instance (Reflection)
  • Cloning of Object
  • Using Classloader
  • Using Object De-Serialization

To make a singleton class you have to disable all these ways to create an object. One way to achieve this is to make the constructor of a given class private. But when you make the constructor private there is no way to create even a single object of the class.  So first make a constructor private and then prepare a way to create an object(Single) of that class.

Implementation One

Here we will create a private Constructor and also a static method to create an object of the same class.

class JBT {

	/*
	 * This variable will be used to hold reference of JBT class.
	 */
	private static JBT instance = null;

	/*
	 * As private constructor is used so can not create object of this class
	 * directly. Except by using static method of same class.
	 */
	private JBT() {

	}

	/*
	 * This method will be used to get instance of JBT class. This method will
	 * check if there is aready an object of class create or not if not then it
	 * will create an Obect of JBT class and return the same else it will return
	 * the existing Object.
	 */
	static JBT createInstance() {
		if (instance == null){
                     instance = new JBT();
                     return instance;
              }
		else
			return instance;
	}

	int i;
}

Problem

What will happen if 2 different thread enters the createInstance method at the same time when the instance is null. In that case, threads will create 2 different objects of JBT. Which is against the Singleton pattern. In the next approach, this problem can be solved.

Implementation Two

In this approach, we will make createInstance method synchronized so only one thread is allowed in that class and only one object will be created instead of Two.

class JBT {

	/*
	 * This variable will be used to hold reference of JBT class.
	 */
	private static JBT instance = null;

	/*
	 * As private constructor is used so can not create object of this class
	 * directly. Except by using static method of same class.
	 */
	private JBT() {

	}

	/*
	 * This method will be used to get instance of JBT class. This method will
	 * check if there is aready an object of class create or not if not then it
	 * will create an Obect of JBT class and return the same else it will return
	 * the existing Object.
	 * 
	 * Now method is marked as synchronized hence only one threa will be allowed
	 * to enter in this method hence only one object will be created.
	 */
	static synchronized JBT createInstance() {
		if (instance == null){
instance = new JBT();
return instance;
}
		else
			return instance;
	}

	int i;
}

Problem

The moment we use synchronized keyword it will create a problem for our multi-threaded application in terms of performance. So on one side, we are resolving the problem on another side we are creating one more problem. In the next approach, we will solve both this problem.

Implementation Three

class JBT {

	/*
	 * This variable will be used to hold reference of JBT class.
	 * 
	 * Here we are creating the instance of JBT class and assigning the
	 * reference of that object to instance.
	 */
	private static JBT instance = new JBT();

	/*
	 * As private constructor is used so can not create object of this class
	 * directly. Except by using static method of same class.
	 */
	private JBT() {

	}

	/*
	 * This method will be used to get instance of JBT class. This method will
	 * check if there is already an object of class create or not if not then it
	 * will create an Object of JBT class and return the same else it will
	 * return the existing Object.
	 * 
	 * synchronized keyword is not required here.
	 */
	static JBT createInstance() {
		/*
		 *  As instance is already create and class loading time hence we can
		 *  directly return the same without creating any object.
		 */
		return instance;
	}

	int i;
}

Problem

Here we are creating the object of JBT when class gets loaded. The object gets created even when it is not required. The object should be created only when it is required(Lazy Loading).  In the next approach, we will try to resolve this problem by using Double checking locking.

Implementation Four

package com.jbt;

public class SingletonExample {

}

class JBT {

	/*
	 * This variable will be used to hold reference of JBT class.
	 * 
	 * Here we are creating the instance of JBT class and assigning the
	 * reference of that object to instance.
	 */
	private static JBT instance = null;

	/*
	 * As private constructor is used so can not create object of this class
	 * directly. Except by using static method of same class.
	 */
	private JBT() {

	}

	/*
	 * This method will be used to get instance of JBT class. This method will
	 * check if there is already an object of class create or not if not then it
	 * will create an Object of JBT class and return the same else it will return
	 * the existing Object.
	 * 
	 * Now block is marked as synchronized instead of whole method. So synchronized
	 * part will be used only once and that is when object is null. 
	 */
	static JBT createInstance() {
		if (instance == null)
		{
			synchronized(JBT.class){
				if (instance == null){
                                   instance = new JBT();
                                   return instance;
                             }
			}
		}

			return instance;
	}

	int i;
}

Problem

All problem has been solved in this approach still synchronized keyword is used(Once) and that should be avoided.

Implementation Five (Initialization on Demand)

class JBT {

	/*
	 * As private constructor is used so can not create object of this class
	 * directly. Except by using static method of same class.
	 */
	private JBT() {

	}

	/*
	 * Here static inner class is used instead of Static variable. It means
	 * Object will be lazy initialized.
	 */
	private static class LazyInit {
		private static final JBT instance = new JBT();
	}

	/*
	 * Whenever object JBT is required this method will be invoked and it will
	 * return the instance of JBT.
	 */
	static JBT createInstance() {
		return LazyInit.instance;
	}

	int i;
}

Problem

What about Object creation using Clone and Serialization?? Next approach will handle that problem.

Implementation Six

To stop cloning of Object we will implement the Cloneable interface and throw CloneNotSupportedException. Also Serialized interface will be implemented and readObject will be used to return only one object at all time.

class JBT implements Cloneable, Serializable{

	@Override
	protected Object clone() throws CloneNotSupportedException {
		return new CloneNotSupportedException();
	}

	protected Object readResolve() {
		return createInstance();
		}

	/*
	 * As private constructor is used so can not create object of this class
	 * directly. Except by using static method of same class.
	 */
	 private  JBT() {

	}

	/*
	 * Here static inner class is used instead of Static variable. It means
	 * Object will be lazy initialized.
	 */
	private static class LazyInit {
		private static final JBT instance = new JBT();
	}

	/*
	 * Whenever object JBT is required this method will be invoked and it will
	 * return the instance of JBT.
	 */
	static JBT createInstance() {
		return LazyInit.instance;
	}

	int i;
}

So this is the final implementation for singleton class. One more approach is there(ENUM). That I will discuss later.

16 Comments Singleton design pattern

  1. Chanchal

    private static JBT instance = null;

    static JBT createInstance() {
    if (instance == null)
    return new JBT();
    else
    return instance;
    }

    Variable ‘instance’ always will be null, i.e createInstance() method always return new object, so how it is Singleton ?

    Reply
    1. JBT

      Hi Chanchal,

      Seems like I missed out something so I corrected the code. New instance should be assigned to variable and then variable should be returned.
      Hope It help now.
      Thanks for pointing out the issue in the code.

      Regards

      Reply
  2. Ramil

    It is not a Singleton pattern. In your code examples createInstance() always returns a new instance of JBT.

    Reply
  3. TH

    public final class SingletonExample {

    private static SingletonExample _instance = null;

    static {
    _instance = new SingletonExample();
    }

    private SingletonExample() {
    if (_instance != null) {
    throw new IllegalStateException(“SingletonExample: duplicate instances not allowed !”);
    }
    }

    public static SingletonExample getInstance() {
    return _instance;
    }
    }

    Reply
  4. aakash

    public class STR1 {

    /**
    * @param args
    */
    public static void main(String[] args) {
    int age = 10;
    String str = ” He is “;
    System.out.println(str);
    }

    Reply
  5. aakash

    class JBT {

    /*
    * This variable will be used to hold reference of JBT class.
    */
    private static JBT instance = null;

    /*
    * As private constructor is used so can not create object of this class
    * directly. Except by using static method of same class.
    */
    private JBT() {

    }

    /*
    * This method will be used to get instance of JBT class. This method will
    * check if there is aready an object of class create or not if not then it
    * will create an Obect of JBT class and return the same else it will return
    * the existing Object.
    */
    static JBT createInstance() {
    if (instance == null)
    return new JBT();
    else
    return instance;
    }

    int i;
    }

    Reply
  6. Adhishree

    both of them are space patterns
    theres a space before 321 and 21 and 1 acc.

    theres a space under 4 in the second one

    Reply
  7. Sanose

    Hello Vivekanand,

    I am just wondering what is the problem with Implementation Three . I was going through the Java specifications and wonder why the object gets created on Heap before the createInstance is invoked.

    Java specs say that a static initializer only happens broadly in this case when either the static method is invoked or when the static variable is assigned. Since this static variable is private assignment cannot happen outside of Class. This means only invocation of the createInstance will create the object on the heap.

    When the class gets loaded preparation involves only the static fields or constants to be intialized into default values, this is not the invocation of the intializer in source code. I understand this as the instance of JBT being initialized with default values perhaps on the stack.

    Perhaps if I see both Implementation Three and Four are both creating this object on class loading with default values and only on createInstance the objects gets created on heap. Is this correct understanding?

    Java Specification says this:

    12.4. Initialization of Classes and Interfaces

    Initialization of a class consists of executing its static initializers and the initializers for static fields (class variables) declared in the class.

    Initialization of an interface consists of executing the initializers for fields (constants) declared in the interface.

    Before a class is initialized, its direct superclass must be initialized, but interfaces implemented by the class are not initialized. Similarly, the superinterfaces of an interface are not initialized before the interface is initialized.
    12.4.1. When Initialization Occurs

    A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

    T is a class and an instance of T is created.

    T is a class and a static method declared by T is invoked.

    A static field declared by T is assigned.

    A static field declared by T is used and the field is not a constant variable (§4.12.4).

    T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.

    A reference to a static field (§8.3.1.1) causes initialization of only the class or interface that actually declares it, even though it might be referred to through the name of a subclass, a subinterface, or a class that implements an interface.

    Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization.

    A class or interface will not be initialized under any other circumstance.

    12.3.2. Preparation of a Class or Interface Type

    Preparation involves creating the static fields (class variables and constants) for a class or interface and initializing such fields to the default values (§4.12.5). This does not require the execution of any source code; explicit initializers for static fields are executed as part of initialization (§12.4), not preparation.

    Reply
    1. Vivekanand Gautam

      Hi Sanose,

      Sorry for late reply. I am completely agree with your point. And i am
      still trying to collect what exactly made me write that in article.

      All the points you have mentioned from doc is proper and loading of
      class happens in the same way. Main problem with different
      approaches(3 and 4) are related to lazy loading of classes. That i
      will check and let you know if it really happens or not.

      Thanks

      Reply

Leave A Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.