Java Singleton Pattern
In this page:
Eager Initialization
Eager initialization creates the Singleton's one and only instance the moment the class is loaded by the JVM, regardless of whether it ends up being used. It's the simplest approach to implement, but its drawback is that it always pays the cost of instantiation even in a run where the singleton is never actually needed.
Example: Eager Initialization
public class Main {
static class Singleton {
static final Singleton INSTANCE = new Singleton(); // created at class-load time, whether used or not
private Singleton() {}
}
public static void main(String[] args) {
System.out.println(Singleton.INSTANCE == Singleton.INSTANCE);
}
}
Login to try C/C++/Java/PHP code in the editor
Lazy Initialization
Lazy initialization instead delays creating the instance until the first time it's actually requested, avoiding unnecessary work up front. To make lazy initialization safe under concurrent access, the creation logic needs to be wrapped in a synchronized method or block so two threads can't both create separate instances.
Example: Lazy Initialization
public class Main {
static class Singleton {
private static Singleton instance;
private Singleton() {}
static synchronized Singleton getInstance() {
if (instance == null) instance = new Singleton(); // created only when first requested
return instance;
}
}
public static void main(String[] args) {
System.out.println(Singleton.getInstance() == Singleton.getInstance());
}
}
Login to try C/C++/Java/PHP code in the editor
Double-Checked Locking
Double-checked locking reduces the overhead of synchronizing on every single access by checking whether the instance already exists twice: once before acquiring the lock, and once again after acquiring it, only creating the instance if it's still missing both times. The instance field must be declared volatile for this pattern to be safe, since without it, other threads could observe a partially-constructed object.
Example: Double-Checked Locking
public class Main {
static class Singleton {
private static volatile Singleton instance;
private Singleton() {}
static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) instance = new Singleton();
}
}
return instance;
}
}
public static void main(String[] args) {
System.out.println(Singleton.getInstance() == Singleton.getInstance());
}
}
Login to try C/C++/Java/PHP code in the editor
Enum Singleton
Enum singletons get thread safety and protection against duplicate instantiation via serialization essentially for free, courtesy of guarantees baked into how the JVM handles enums. Many experienced Java developers consider this the simplest and most robust way to implement a Singleton in practice.
Example: Enum Singleton
public class Main {
enum Singleton {
INSTANCE;
void doWork() { System.out.println("Working"); }
}
public static void main(String[] args) {
Singleton.INSTANCE.doWork(); // thread-safe and serialization-safe for free
}
}
Login to try C/C++/Java/PHP code in the editor
Serialization & Reflection Protection
A conventional (non-enum) Singleton can accidentally end up duplicated during deserialization, or even via reflection forcibly calling a private constructor a second time. Implementing the readResolve() method lets you intercept deserialization and return the existing singleton instance instead of a new one.
Example: Serialization & Reflection Protection
import java.io.*;
public class Main {
static class Singleton implements Serializable {
static final Singleton INSTANCE = new Singleton();
private Singleton() {}
protected Object readResolve() {
return INSTANCE; // returns the existing instance instead of a new one during deserialization
}
}
public static void main(String[] args) {
System.out.println(Singleton.INSTANCE);
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 14 topics to unlock
0/14 topics done
Complete these topics first:
- Java Design Patterns Introduction
- Java Singleton Pattern
- Java Factory Pattern
- Java Observer Pattern
- Java Builder Pattern
- Java MVC Architecture
- Java Adapter Pattern
- Java Decorator Pattern
- Java Strategy Pattern
- Java Command Pattern
- Java Facade Pattern
- Java Proxy Pattern
- Java Template Method Pattern
- Java Repository Pattern