Singleton Pattern

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

Singleton Pattern Diagram

Implementation

Lazily-created singleton

public class Singleton {
	private static Singleton uniqueInstance;
	
	private Singleton() {}
	
	public static synchronized Singleton getInstance() {
		if (uniqueInstance == null) {
			uniqueInstance = new Singleton();
		}
		return uniqueInstnace;
	}
}

Eagerly-created singleton

public class Singleton {
	private static Singleton = new Singleton();
	
	private Singleton() {}
	
	public static synchronized Singleton getInstance() {
		return uniqueInstance;	
	}
}

Double-checked Locking Pattern

public class Singleton {
	
	/*
	volatile: safely publishes the completed object to threads that skip synchronization */
	private volatile static Singleton uniqueInstance;
 
	private Singleton() {}
 
	/* Double-checked locking pattern for synchronization optimization */
	public static Singleton getInstance() {
	/* First check: should i try to acquire the lock? */
		if (uniqueInstance == null) {
			/* Providing mutual exclusion here */
			synchronized (Singleton.class) {
				/* Second check: after acquiring the lock, is initialization still necessary? */
				if (uniqueInstance == null) {
					uniqueInstance = new Singleton();
				}
			}
		}
		return uniqueInstance;
	}
  
	// other useful methods here
	public String getDescription() {
		return "I'm a thread safe Singleton!";
	}
}

Singleton using Enum

public enum Singleton {
	UNIQUE_INSTANCE;
	// other useful fields here
	// other useful methods here
	
	public String getDescription() {
		return "I'm a thread safe Singleton!";
	}
}

Enum

An enum singleton works because Java nad the JVM enforce three separate guarantees

  1. Java prevents additional instances.

    Enum constructors are implicitly private. You cannot write: new Singleton();
    You also can’t subclass an enum to create another instance because every enum is implicitly final.

  2. The JVM initializes the enum class exactly once.

    The JVM guarantees that each class is initialized at most once per class loader.

  3. Initialization is safely published.

    Java guarantees a happends-before relationship between:
    - Completion of Singleton class initialization
    - Any thread subsequently using Singleton