All topics
library
intermediate

Singleton Pattern & Thread Safety

Implement thread-safe singletons correctly, and know why the double-checked locking idiom requires volatile.

The Singleton pattern ensures a class has exactly one instance. In Java, thread-safe implementation is tricky.

Singleton = a country's president. There's exactly one at any time. The enum approach = it's written in the constitution (bulletproof). Double-checked locking = asking two guards independently and hoping they agree (fragile without proper protocol/volatile).

Key Concepts

1
Approaches (best to worst):
2
1. Enum singleton (recommended by Effective Java): enum Singleton { INSTANCE; } Thread-safe, serialization-safe, reflection-safe. Simplest.
3
2. Static holder (Bill Pugh pattern): Private static inner class holds the instance. Lazily initialized by the JVM's class loading guarantee. Thread-safe without synchronization.
4
3. Double-checked locking: volatile field + synchronized block. Correct since Java 5 (volatile prevents instruction reordering). Commonly asked in interviews but enum/holder is simpler.
5
4. Synchronized method: synchronized getInstance(). Thread-safe but locks on every call (poor performance).
6
5. Eager initialization: static final INSTANCE = new Singleton(). Simple but not lazy.
7
Why double-checked locking needs volatile: Without volatile, the JVM may reorder the write: (1) allocate memory → (2) assign reference → (3) call constructor. Thread B might see the reference (step 2) before the constructor finishes (step 3), getting a partially constructed object. volatile prevents this reordering.
8
Modern alternatives: In Spring, @Service/@Component beans are singletons by default (container-managed). In most applications, you don't need to implement singleton yourself.