Mastering the Singleton Pattern in Java: Eager, Lazy, and Thread‑Safe Implementations
This article explains the concept of design patterns and dives deep into the Singleton pattern in Java, covering its purpose, eager and lazy implementations, thread‑safety challenges, double‑checked locking, volatile usage, static inner class, and enum approaches, while illustrating each with clear code examples and diagrams.
Design patterns are reusable solutions to common software design problems; they improve code reusability, readability, and reliability.
Singleton Pattern
The Singleton ensures that a class has only one instance that is globally accessible, similar to how no two identical leaves exist on Earth.
There are two main categories:
Eager (饿汉) mode – the instance is created when the class is loaded.
Lazy (懒汉) mode – the instance is created upon first use.
Eager Mode
A basic implementation can be illustrated as follows:
This approach is simple but may waste resources if the instance is created too early, especially when the singleton consumes significant resources.
Class Loading Timing
When a new object is created.
When an instance is created via reflection.
When a subclass is loaded before its superclass.
When the JVM loads the main class at startup.
Lazy Mode
Typical lazy implementation:
If multiple threads call getInstance() simultaneously, both may see instance == null and create separate objects, breaking the singleton guarantee.
Adding synchronized to the method ensures only one thread can execute the critical section at a time:
While this prevents duplicate instances, it can degrade performance because all threads except the one holding the lock must wait.
Double‑Check Locking
To reduce synchronization overhead, double‑check locking adds two if (instance == null) checks:
The first check avoids entering the synchronized block when the instance already exists.
The second check ensures that only one thread creates the instance.
However, this pattern still suffers from issues related to atomicity and instruction reordering.
Atomic Operation
An atomic operation cannot be interrupted by thread scheduling. For example: m = 6; // atomic operation In contrast, a declaration with assignment is not atomic:
int n = 6; // not atomicInstruction Reordering
Compilers may reorder independent statements to improve performance, e.g.:
int a; // statement 1
a = 8; // statement 2
int b = 9; // statement 3
int c = a + b; // statement 4Execution order might become 3‑1‑2‑4 or 1‑3‑2‑4 without affecting the final result.
During singleton creation, the steps are:
Allocate memory for the instance.
Invoke the constructor to initialize fields.
Assign the reference to the variable.
Instruction reordering can swap steps 2 and 3, causing another thread to see a non‑null reference before the object is fully initialized, leading to errors.
The fix is to declare the instance variable as volatile, which prevents reordering of these steps:
Using volatile creates a memory barrier, ensuring that writes to the instance are completed before any read can occur.
Other Implementations
Static Inner Class
The inner class SingletonHolder is loaded lazily by the class loader, guaranteeing thread‑safe lazy initialization without explicit synchronization.
Enum
Enum singletons are simple, efficient, and inherently thread‑safe due to Java’s built‑in serialization mechanism.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
