Design patterns

The Singleton pattern

The Singleton Pattern ensures a class has only one instance, and provides a global point of access to it.

The Singleton Pattern:

ensures a class has only one instance, and provides a global point of access to it.

This pattern ensures that there is only one instance of a class in the application and provides a global access point to it. Java’s implementation of the Singleton Pattern uses a private constructor, a static method combined with a static variable. Singleton implementation could be greatly simplified with enums. Singleton violates loose coupling design principle.

How it works (code examples):

  1. The most primitive implementation

Here constructor is private, so only getUniqueInstance() method could return Singleton class instance.

public class SingleInstanceClass {
	private static SingleInstanceClass uniqueInstance;
	private SingleInstanceClass() {}
	
	public static SingleInstanceClass getUniqueInstance() {
		if (uniqueInstance == null) {
			uniqueInstance = new SingleInstanceClass();
		}
		return uniqueInstance;
	}
}

2. Implementation ready for multithreading

Synchronizing getUniqueInstance() method can decrease performance noticeably and is only needed when calling this method the first time.

public class SingleInstanceClass {
	private static SingleInstanceClass uniqueInstance;
	private SingleInstanceClass() {}
	
	public static synchronized SingleInstanceClass getUniqueInstance() {
		if (uniqueInstance == null) {
			uniqueInstance = new SingleInstanceClass();
		}
		return uniqueInstance;
	}
}
  1. Thread-safe implementation of eager singleton instance creation

Useful only if the creation of singleton does not take a lot of time and resources. JVM will create a unique instance of SingleInstanceClass when the class is loaded and before any thread can access the static uniqueInstance variable.

public class SingleInstanceClass {
	private static SingleInstanceClass uniqueInstance = new SingleInstanceClass();
	private SingleInstanceClass() {}
	
	public static SingleInstanceClass getInstance() {
		return uniqueInstace;
	}
}
  1. Thread-safe double-checked locking implementation

Synchronization is used only the first time when SingleInstance Class is instantiated.

public class SingleInstanceClass {
	private volatile static SingleInstanceClass uniqueInstance;
	private SingleInstanceClass() {}
	
	public static SingleInstanceClass getUniqueInstance() {
		if (uniqueInstance == null) {
			synchronized (SingleInstanceClass.class) {
				if (uniqueInstance == null) {
					uniqueInstance = new SingleInstanceClass();
				}
			}
		}
		return uniqueInstance;
	}
}

5. Safest and simplest singleton pattern implementation using ENUM

Solves synchronization, class loading issues, reflection, and serialization/deserialization issues

public enum Singleton {
	INSTANCE;
	private int count;

	public void setCount(int count) {
		this.count = count;
	}

	public void printCount() {
		System.out.println(this.count);
	}

}
@Test
public void singletonTest() {
  Singleton.INSTANCE.setCount(1);
  Singleton.INSTANCE.printCount();
}

Leave a Reply

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