Java Interview – How to create Thread-safe Singleton class ?

In this article, we will discuss how to write Java code to create Thread-safe Singleton class in a Multi-threaded environment

Before starting to write code for Singleton class, we should know all possible ways to create new Object and then find the way to suppress it

1. Ways to create & suppress Object :

Sr. No.CreationSuppress
1.new keywordProvide private constructor which restricts to create new Object from outside of the class
2.Reflection APIReflection API at runtime allows to create new Object therefore add additional check and throw Runtime Exception
3.De SerializationDe-serializing a file/network stored serialized Object creates new Object so override readResolve() method and return same Singleton instance
4.Cloningclone() method of Cloneable interface allows to clone new Object so override clone() method and throw CloneNotSupportedException
Object creation and suppression technique in Java

2. Singleton Object creation :

Although we have seen different ways to create Object and suppression technique but there must be one such Object available during application lifetime to use this class’ properties/behavior

Therefore, to create Singleton instance in Java there are different ways –

  1. Eager initialization
  2. Lazy initialization
  3. Enum Singleton
  4. Lazy initialization in a Single threaded environment
  5. Lazy initialization with double control lock in a multi-threaded environment

In this illustration, we will see how to create Singleton instance using lazy initialization technique in a multi-threaded environment

LoggerFactory.java

package in.bench.resources.singleton.design;

import java.io.Serializable;

public class LoggerFactory implements Serializable, Cloneable {

	// serialization UID
	private static final long serialVersionUID = 2251319696423032771L;


	// member variable - lazy initialization
	public static LoggerFactory LOGGER = null;


	// 1. private constructor
	private LoggerFactory() {

		// 2. suppress object creation via Reflection API
		if(null != LOGGER) {
			throw new RuntimeException("Not allowed to create object via Reflection API");
		}
	}


	// 3. suppressing object creation via de-serialization 
	public LoggerFactory readResolve() {
		return LOGGER;
	}


	// 4. overriding clone() method to throw Exception
	@Override
	protected Object clone() throws CloneNotSupportedException {
		throw new CloneNotSupportedException();
	}


	/**
	 * returns always singleton instance
	 * @return
	 */
	public static LoggerFactory getLogger() {

		// for performance enhancement/improvement
		if(null == LOGGER) {

			// for multi-threaded environment
			synchronized(LoggerFactory.class) {

				// double control lock
				if(null == LOGGER) {

					// this piece of code will be executed only-once
					LOGGER = new LoggerFactory();
					return LOGGER;
				}
			}
		}
		return LOGGER;
	}
}

Read how to create Singleton class in a single Thread environment

Related Articles :

References:

Happy Coding !!
Happy Learning !!

Java - Why do we use “public static void main” only ?