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
-
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 implicitlyfinal. -
The JVM initializes the enum class exactly once.
The JVM guarantees that each class is initialized at most once per class loader.
-
Initialization is safely published.
Java guarantees a happends-before relationship between:
- Completion of Singleton class initialization
- Any thread subsequently using Singleton