How to implement Singleton pattern in Java?

In most interviews when candidates are asked about design patterns , the first answer that pops up is Singleton pattern!

This pattern has been beaten to pulp ever since design patterns became mainstream.

Still people can go wrong in effectively implementing it.

This post looks into this pattern in detail.

Singleton , as the name hints ensures that only one instance of a class can be created. The entire application will then use this single instance only.

Let’s create a singleton class named SuperStar.

In my state of Tamilnadu, Rajnikanth is called as the one and only SuperStar. People believe there were no Super Stars like him before and there can’t be any Super Star like him ever.

Let’s create a class to create him, the one and only Super Star.

Let’s follow these steps:

STEP 1:

Mark the constructor as private.

Why?

Because no other class should be able to create a new instance of this class.

private SuperStar(){
}

STEP 2:

Declare a static instance of SuperStar in the class and make it private.

Why?

A static instance ensures that only one instance will be created.

Making it private ensures that it cannot be accessed outside the class.

But it can be accessed inside the class.

We will be creating an instance inside a public method inside the class .

private static SuperStar superStar = null;

STEP 3:

Create a static method which returns the singleton instance.

This method can create the instance using lazy loading. If it is not already created then only instantiate it else just return the created instance.

If we had instantiated the class as soon as we had declared it(STEP 2) we could not have utilized the benefit of lazy loading.

public static SuperStar getInstance(){
         if(superStar == null){
                  superStar = new SuperStar();
            }
       return superStar;
}

Thats it.

But the above code works fine only in a single threaded environment.

To make it work in a mulithreaded environment , do the following additional steps:

STEP 4:

Mark the instance as volatile.

volatile keyword makes sure any thread always gets the latest value of a variable.

So if Thread 1 has created the instance , then that will be immediately visible to Thread 2 which checks if the instance is null before creating it.

Otherwise , each thread will have a local copy of the instance variable copied from main memory which may not reflect the latest value.

private static volatile SuperStar superStar = null;

STEP 5:

Even marking the variable as volatile doesn’t make sure that only one instance will be created!

Two threads may both execute line no 3 in STEP 3 at the same time creating two instances.

To overcome this mark the block of code which creates the instance as synchronized:

public static SuperStar getInstance() {
		
	
		if(superStar == null) {
			
			
			synchronized (SuperStar.class) {
				
		
					superStar = new SuperStar();
			
				
			}
		}
		
		return superStar;
	}

Is that enough? No!

Assume Thread 1 has made the null check if(superStar == null) and Thread 2 also has done the same.

Then,

Thread 1 enters the synchronized block.

This blocks Thread 2 from entering it and it waits.

Now ,

Thread 1 creates a new instance and releases the lock.

Thread 2 which had already done the null check and was just waiting outside the synchronized block goes on to create a new instance as well!

To avoid this , do one more null check :

STEP 6:

Add a null check inside the synchronized block where instance is created.

public static SuperStar getInstance() {
		
	
		if(superStar == null) {
			
			
			synchronized (SuperStar.class) {
				
				if(superStar == null) {
					
					superStar = new SuperStar();
				}
				
			}
		}
		
		return superStar;
	}

And that almost looks like , only a single instance can be created in the code now.

But wait again! A new instance can still be created through reflection. To avoid this throw an exception inside the private constructor if a new instance is created:

STEP 7:

Prevent instance creation through reflection:

	private SuperStar() {
		
	
		if(superStar != null) {
			
			throw new RuntimeException("Use getInstance() method");
		}
	}

You can relax now.

There is and will be only one Super Star and his name is Rajnikanth

(you can set this name as well by adding a name field with the value ‘Rajnikanth’)

The complete code is as below :

package creational.singleton.pattern;
public class SuperStar {
	
	private static volatile SuperStar superStar = null;
	
	
	private SuperStar() {
		
	
		if(superStar != null) {
			
			throw new RuntimeException("There can be one and only one Suepr Star!);
		}
	}
	
	public static SuperStar getInstance() {
		
	
		if(superStar == null) {
			
			
			synchronized (SuperStar.class) {
				
				if(superStar == null) {
					
					superStar = new SuperStar();
				}
				
			}
		}
		
		return superStar;
	}
}

An example client code :

package creational.singleton.pattern;
public class Client {
	
	
	public static void main(String a[]) {
		
		SuperStar superStar = SuperStar.getInstance();
		
		System.out.println(superStar);
		
		
		SuperStar secondSuperStar = SuperStar.getInstance();
		
		System.out.println(secondSuperStar);
	}
}

Below is the output :

creational.singleton.pattern.SuperStar@7a81197d
creational.singleton.pattern.SuperStar@7a81197d

Note that only one object is created as the identifiers indicate.

All the above changes done for ensuring thread safety looks quite complicated.

An alternative and simple solution to this problem is to use Enums.

They reduce the verbosity of the code and ensure only one instance is created as well.

Here is an enum for the Super Star:

package creational.singleton.pattern;
public enum SuperStarEnum {
	
	SUPER_STAR;
	
	private String name;
	
	
	public String getName() {
		
		return name;
	}
	
	public void setName(String name) {
		
		this.name = name;
	}
}

The SuperStarEnum object can be read in client code the below way:

SuperStarEnum superStarEnum = SuperStarEnum.SUPER_STAR;
		

The name of Super Star Enum can be set in the usual way:

		superStarEnum.setName("Rajnikanth");

Simple and Effective!

The Gang of Four define the Singleton pattern as

Ensure a class has only one instance and provide a global point of access to it

The Gang of Four has mentioned one more applicability for the pattern . That is to subclass the singleton class and allow for more than one type of singletons to be created .

Quoting them :

Use the singleton pattern when :

– there must be exactly one instance of a class and it must be accessible to clients from a well know access point

– when the sole instance should be extensible by subclassing , and client should be able to use an extended instance without modifying their code

The second point is not dealt with in this post. It is rarely used as well in Java code. They also suggest we can keep a registry of singletons which can be looked upon by the client for their required singleton object.

Here is the github URL for the code :

https://github.com/vijaysrj/designPatternsGoF/tree/master/src/creational/singleton/pattern


Posted

in

,

by

Comments

2 responses to “How to implement Singleton pattern in Java?”

  1. Prathap Avatar
    Prathap

    how about clone and de-serialization issues. must override clone and read Resolve

    1. Vijay SRJ Avatar
      Vijay SRJ

      Can you please elaborate on those issues..

Leave a Reply

Discover more from The Full Stack Developer

Subscribe now to keep reading and get access to the full archive.

Continue reading