skip to content

Singleton in Java

Every Java way to build a singleton — eager, double-checked locking with volatile, the static holder idiom, and the enum — plus the four ways the guarantee is broken (reflection, serialization, cloning, multiple classloaders). Interviewers ask why volatile is mandatory in double-checked locking and why the enum form is immune to all of it.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

4

What is the Singleton pattern, and what are the common ways to implement it in Java?

level: juniorimportance: must knowfreq 75%

answer

  1. private constructor + static field + getInstance()
  2. eager / lazy / holder / enum
  3. holder = lazy + thread-safe, no lock
  4. enum = Bloch's best, attack-proof
  5. Runtime.getRuntime() is the JDK example

basics

~20 s

A Singleton ensures a class has exactly one instance and gives global access to it. In Java you hide the constructor (make it private) and expose one shared instance, either created eagerly in a static field or lazily in a getInstance() method.

solid answer

~50 s

A Singleton guarantees one instance of a class per JVM and a single global access point. The mechanics are always: a private constructor (so no one can call new), a static field holding the one instance, and a static accessor that returns it. Common idioms: (1) eager init - assign the instance in the static field directly, created at class load, simple and thread-safe; (2) lazy init - create it on first getInstance() call, which needs care to stay thread-safe; (3) the static holder idiom - a private nested class holds the instance, giving lazy + thread-safe with no locking; (4) the enum singleton - a single-constant enum, which Effective Java recommends because it is concise and immune to reflection and serialization attacks. A JDK example is Runtime.getRuntime(). The pattern is criticized for hidden global state and harder testing, so prefer dependency injection where you can.

go deeper

for a junior

Can state the intent (one instance, global access) and write the private-constructor + static-getInstance() form; recognizes Runtime.getRuntime().

for a middle

Distinguishes eager vs lazy and knows the naive lazy version is not thread-safe; can write the static-holder idiom and explain why it is lazy and safe.

for a senior

Picks the idiom deliberately (holder vs enum), articulates the testability/global-state downsides, and reaches for dependency injection instead of hard singletons where appropriate.

for a principal

Frames singletons as an application-scope/lifecycle concern, weighs container-managed single instances (Spring beans) vs language singletons, and sets team conventions around when a true singleton is justified.

## What problem does Singleton solve? Sometimes exactly one object should exist for a whole program: a configuration registry, a connection pool, a logging facility. The **Singleton pattern** (from the Gang of Four design-patterns book) ensures a class has **exactly one instance** and provides a **single global point of access** to it. ### The core mechanics Three ingredients appear in every Java singleton: 1. A **private constructor** - so outside code cannot write `new MyClass()`. (A constructor is the special method that builds an object; making it `private` means only the class itself can call it.) 2. A **static field** holding the one instance. (`static` means the field belongs to the class itself, not to any object - there is exactly one copy shared by everyone.) 3. A **static accessor** (conventionally `getInstance()`) that returns that one instance. ### Idiom 1 - Eager initialization ```java public final class Config { private static final Config INSTANCE = new Config(); private Config() {} public static Config getInstance() { return INSTANCE; } } ``` The instance is built when the class is **loaded** (the JVM loads a class the first time it is used). The JVM guarantees class initialization happens once and is thread-safe, so this is automatically safe across threads. The only downside: the object is created even if you never call `getInstance()`. For a cheap object that does not matter. ### Idiom 2 - Lazy initialization Build the instance only on the first `getInstance()` call (saves work if it is never used). A naive lazy version is **not thread-safe**: two threads could both see `null` and both create an instance. Making it safe requires either a `synchronized` accessor (correct but slow because every call locks) or the more advanced double-checked-locking idiom (covered in its own question). ### Idiom 3 - Static holder (initialization-on-demand holder) ```java public final class Config { private Config() {} private static class Holder { static final Config INSTANCE = new Config(); } public static Config getInstance() { return Holder.INSTANCE; } } ``` The nested `Holder` class is loaded only when `getInstance()` first touches `Holder.INSTANCE`. So creation is **lazy** (deferred to first use) and **thread-safe** (the JVM's once-only class-init guarantee), with **no locking** on the hot path. This is the recommended idiom for a class-based singleton. ### Idiom 4 - Enum singleton ```java public enum Config { INSTANCE; public void doWork() { /* ... */ } } ``` An `enum` with a single constant is a singleton: the JVM creates exactly one `INSTANCE`. *Effective Java* (Joshua Bloch) calls this the best way, because it is concise and the language itself blocks the usual attacks - you cannot reflectively call an enum constructor, and enum serialization is handled specially so you never get a second copy. ### A JDK example `Runtime.getRuntime()` returns the one `Runtime` object representing the running JVM - a real, eager singleton in the standard library. ### Why people criticize Singletons A singleton is **global mutable state**, which makes code harder to test (you cannot easily swap in a fake) and hides dependencies. Modern designs often prefer **dependency injection** - create one instance and pass it where needed - over a hard-coded singleton. Knowing the pattern is essential; using it everywhere is a smell.

  • Why does Effective Java recommend the enum singleton over a class with a private constructor?
    Because a single-element enum is concise, the JVM guarantees one instance, and the language itself blocks reflection (you cannot reflectively instantiate an enum) and provides correct serialization for free - so it is immune to the attacks that break class-based singletons.
  • Is Runtime.getRuntime() lazy or eager?
    Eager - the single Runtime instance is held in a static final field initialized when the Runtime class loads, so getRuntime() just returns the already-built object.

saying these in an interview costs you the question

  • Saying a singleton is just 'a static class' - a singleton is an object with a private constructor, not a class of static methods.
  • Claiming the naive lazy getInstance() is thread-safe - it is not.
  • Forgetting the private constructor, so callers can still write new.
  • Believing every shared service must be a Singleton; dependency injection is usually better.

context

open as a page

Explain thread-safe lazy initialization in Java: why is double-checked locking broken without volatile, and how do you fix it?

level: seniorimportance: must knowfreq 70%

basics

~20 s

If two threads create a lazy singleton at the same time you can get two instances. Double-checked locking checks the field, locks only if it is null, then checks again. Without the volatile keyword on the field, another thread can see a half-built object, so you must mark the field volatile.

open as a page

How can a class-based Java singleton's single-instance guarantee be broken, and how do you defend against each attack?

level: seniorimportance: should knowfreq 55%

basics

~20 s

Even with a private constructor, reflection can call it, deserialization can build a second object, and clone() can copy it. Defend by throwing from the constructor if an instance exists, adding readResolve() to return the existing instance, and refusing to clone. Or just use an enum singleton, which blocks all of these.

open as a page

When is a Singleton the right choice in Java, and what alternatives (like dependency injection) should you prefer?

level: principalimportance: should knowfreq 50%

basics

~20 s

Use a true Singleton only when there genuinely must be one instance, like a registry or a hardware accessor. For most shared services, create one instance and pass it where needed (dependency injection) instead, because hard-coded singletons are global state and hard to test.

open as a page