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. | Creation | Suppress | 
| 1. | new keyword | Provide private constructor which restricts to create new Object from outside of the class | 
| 2. | Reflection API | Reflection API at runtime allows to create new Object therefore add additional check and throw Runtime Exception | 
| 3. | De Serialization | De-serializing a file/network stored serialized Object creates new Object so override readResolve() method and return same Singleton instance | 
| 4. | Cloning | clone() method of Cloneable interface allows to clone new Object so override clone() method and throw CloneNotSupportedException | 
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 –
- Eager initialization
 - Lazy initialization
 - Enum Singleton
 - Lazy initialization in a Single threaded environment
 - 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 :
- Java – Singleton design pattern, restricting all 4 ways of Object creation
 - Java – How to construct a singleton class in a multi-threaded environment ?
 
References:
- https://www.benchresources.net/singleton-design-pattern-with-java-serialization/
 - http://www.oracle.com/technetwork/articles/java/singleton-1577166.html
 - http://www.javaworld.com/article/2074979/java-concurrency/double-checked-locking–clever–but-broken.html
 
Happy Coding !!
Happy Learning !!