Singleton Pattern
Ensure a class has exactly one instance and provide a global access point to it. Use when exactly one object must coordinate actions across the system.
Singleton = Highlander: 'There can be only one.' One ring, one throne, one instance. But unlike the movie, your singleton is a global celebrity everyone secretly depends on — famous and hard to replace.
The naive implementation (static instance, synchronized getInstance) synchronizes on every call. The better approach is the initialization-on-demand holder: a private static inner class holds the instance, initialized by the JVM's class loader — which is inherently thread-safe and lazy. Alternatively, use a Java enum Singleton (serialization-safe, reflection-safe). Common use cases: thread pool, configuration manager, logging service, connection pool.
Singleton has three thread-safety concerns: (1) visibility — without volatile, the JVM may reorder the constructor and assignment, leaving another thread with a partially constructed object; (2) atomicity — check-then-act on null is not atomic; (3) the JVM double-checked locking fix requires volatile in Java 5+ because the Java Memory Model was fixed in JSR-133. The enum Singleton avoids all three: the JVM guarantees each enum value is instantiated exactly once. The deeper critique of Singleton is architectural: it is a global variable with a design-pattern coat. It makes classes that depend on it hard to test (cannot be mocked without reflection or PowerMock) and creates hidden coupling. In most modern code, Singleton is replaced by a DI container scope — the framework controls the lifecycle, your code just declares it wants a single instance.
I implement Singleton via the initialization-on-demand holder idiom: a private static nested class holds the instance field, which is initialized when the holder class is first loaded. JVM class loading is lazy and thread-safe, so this gives us lazy initialization and thread-safety with zero synchronization overhead on the hot path. In a modern codebase I'd mark it as a singleton scope in a DI framework rather than hardcoding the pattern — it's testable and the lifecycle is explicit.
Double-checked locking without volatile is broken in Java before 5.0. Even in Java 5+, the instance field must be volatile to prevent the JVM from publishing a partially constructed object due to instruction reordering. The safe alternatives are: volatile DCL, enum Singleton, or the holder idiom.