Singleton
Beginner · 15 min read · Low-Level Design, Creational Patterns
One instance, thread-safe initialisation, and why it is often an anti-pattern.
The idea in plain words
Some things should exist only once in a running program, such as the settings everyone reads or one shared connection pool. A Singleton is a class that makes sure only one object of it is ever created, and hands that same object to everyone who asks.
The problem
Some resources should exist once per process: a configuration registry loaded at startup, a connection pool, an in-memory cache shared by all requests, a metrics registry. Creating several would waste resources or cause inconsistency (two caches holding different data).
The structure
Implementations in Java
Thread-safe for free — the JVM initialises static fields during class initialisation, which is guaranteed to happen once. Downside: created even if never used (rarely matters).
Breaking a singleton (and defending it)
Why Singleton is often an anti-pattern
The better default: create one instance at startup and inject it where needed. You get "single instance" without "global access":
Where you've seen it
When to use
Avoid for anything you want to mock in tests, anything with mutable business state, or as a shortcut to avoid passing dependencies.
Related patterns
Interview questions
- Why is the volatile keyword required in double-checked locking?
- Which singleton implementation would you choose and why?
- How would you unit-test code that calls a singleton's getInstance()?
- Is a Spring singleton bean the same as the GoF Singleton?
Further reading
Key takeaways
- Singleton = private constructor + static instance + static accessor.
- Naive lazy init is a race; DCL needs volatile; the holder idiom and enum are the clean, thread-safe options.
- Defend against reflection, serialization and cloning — or use an enum.
- Prefer one injected instance over a global static accessor for testability and loose coupling.
Previous: Core Design Principles · Next: Factory Method & Abstract Factory