Which is the safest way to write a thread-safe Singleton in Java?
Options
- A public static field that is initialized lazily with no synchronization
- A single-element
enum, or a holder class with a static final instance (Correct option) - A normal class with a public constructor that anyone can call
- A class whose fields are all marked with the
volatilekeyword
Answer
A single-element enum, or a holder class / eager static final instance
Why
Singleton means one instance for the whole application. Lazy initialization with if (instance == null) instance = new X(); is NOT thread-safe: two threads could create two instances.
Safe options:
enum Config { INSTANCE; ... }: the JVM guarantees one instance and it also survives serialization and reflection attacks (recommended by Effective Java).- Eager
private static final X INSTANCE = new X();. - Initialization-on-demand holder idiom (a private static inner class holding the instance).
- Double-checked locking works only if the field is
volatile.
In Spring apps, usually let the container manage singleton beans instead.
public enum AppConfig {
INSTANCE;
public String env() { return "prod"; }
}
// AppConfig.INSTANCE.env()Remember
Java Singleton: prefer enum or let Spring manage it.