BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ Design patterns and architecture

Java language

Singleton pattern

A singleton guarantees one shared instance of a class: a private constructor plus a static accessor.

Learn these first

At a glance

Mental model

The mayor of a town: there is exactly one, everybody asks the same person, and nobody else can hold the office.

What happens, in order
  1. 1The simplest safe forms: an enum (enum Config { INSTANCE; ..}), an eager static field (private static final Config INSTANCE = new Config();), or a holder class that loads lazily (private static class Holder { static final Config I = new Config(); }).
  2. 2Lazy creation with if (instance == null) instance = new X(); is not thread safe: two threads may create two instancesFix with double-checked locking and a volatile field, or use the holder idiom.
  3. 3The private constructor stops new, but reflection, serialization (readResolve) and multiple class loaders can still create copies, which an enum prevents
  4. 4In Spring every bean is a singleton per container by default, managed for you, which is the better form: the object is created once and passed in where needed
Remember
Watch out
Lazy initialisation without synchronisationDouble-checked locking without volatileA mutable singleton used as a global variableForgetting that each class loader gets its own "singleton"
Example (highlighted lines explain it)
public class Registry {  private static volatile Registry instance;  private final java.util.Map<String, String> entries = new java.util.concurrent.ConcurrentHashMap<>();  private Registry() {}  public static Registry getInstance() {    if (instance == null) {      synchronized (Registry.class) { if (instance == null) instance = new Registry(); }    }    return instance;  }  public void register(String k, String v) { entries.put(k, v); }}
Read the full explanation (about 1 min)

A singleton guarantees one shared instance of a class: a private constructor plus a static accessor. It is easy to write, easy to get wrong with threads, and hard to test; dependency injection usually replaces it.

A mental model

The mayor of a town: there is exactly one, everybody asks the same person, and nobody else can hold the office.

How it works

The simplest safe forms: an enum (enum Config { INSTANCE; ... }), an eager static field (private static final Config INSTANCE = new Config();), or a holder class that loads lazily (private static class Holder { static final Config I = new Config(); }).

Lazy creation with if (instance == null) instance = new X(); is not thread safe: two threads may create two instances. Fix with double-checked locking and a volatile field, or use the holder idiom.

The private constructor stops new, but reflection, serialization (readResolve) and multiple class loaders can still create copies, which an enum prevents.

In Spring every bean is a singleton per container by default, managed for you, which is the better form: the object is created once and passed in where needed.

Going deeper

Singletons are global state in disguise: hidden dependencies, hard to replace in a test, and trouble when you later need two of them (two tenants, two databases). Prefer passing dependencies explicitly.

A singleton that holds mutable state needs its own thread safety, or it becomes a shared race condition for the whole program.

Under the hood

The holder idiom works because the JVM initialises a class lazily and exactly once under a lock, so the inner class is loaded on first use of getInstance() without any explicit synchronisation.

Common mistakes

  • Lazy initialisation without synchronisation.
  • Double-checked locking without volatile.
  • A mutable singleton used as a global variable.
  • Forgetting that each class loader gets its own "singleton".

How Unravel recognises it

When you paste code, Unravel looks for these signs of singleton pattern. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is Singleton pattern?

A singleton guarantees one shared instance of a class: a private constructor plus a static accessor. It is easy to write, easy to get wrong with threads, and hard to test; dependency injection usually replaces it.

What are the most common mistakes with Singleton pattern?

Lazy initialisation without synchronisation. Double-checked locking without volatile. A mutable singleton used as a global variable. Forgetting that each class loader gets its own "singleton".

How can I see Singleton pattern in real code?

Paste your own Java into Unravel and it will point out where singleton pattern appears, explain how it works at the detail level you choose, and draw the flow of the code around it.