Last Updated: 25.02.2026
Singleton is a Creational Design Pattern that ensures:
- Only one instance of a class exists
- Provides a global access point to that instance
- It controls object creation.
In many applications, we need exactly one instance of a class throughout the entire lifecycle of the application.
Creating multiple instances may lead to:
⚠️ Inconsistent state- 🔥 Resource conflicts
- 🧠 Unnecessary memory usage
- 🔌 Duplicate database connections
Imagine, You are building a backend system where:
📂 The application reads configuration from a file
🔄 Multiple services need access to the same configuration
Now think about what happens if every service creates its own configuration object:
- 📖 The file will be read multiple times
- 💾 Memory will be wasted
- ❌ Application state may become inconsistent
That’s inefficient and risky.
🚨 We Need
- ✅ Only one configuration object
- 🌍 Accessible globally
- 🧵 Thread-safe
- ⚡ Efficient and optimized
The Solution to the above problem is Singleton Design Pattern, It ensures that:
- 🏗 Only one instance of a class is created
- 🔐 Controlled access to that instance
- 🌎 A global access point
- 🧵 Thread safety (when implemented properly)
| Component | Responsibility |
|---|---|
| Singleton Class | Holds the single instance |
| Private Constructor | Prevents external instantiation |
| Static Access Method | Returns the single instance |
🧠 Mental model: Private constructor + static instance + static accessor
package com.designpatterns.singleton;
public class EagerSingleton {
private static final EagerSingleton INSTANCE = new EagerSingleton();
// Prevent Instantiation
private EagerSingleton() {
}
public static EagerSingleton getInstance() {
return INSTANCE;
}
}package com.designpatterns.singleton;
public class LazySingleton {
private static LazySingleton instance = null;
// Prevent Instantiation
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}❌ Breaks in multithreaded environment
package com.designpatterns.singleton;
public class ThreadSafeSingleton {
private static ThreadSafeSingleton instance = null;
// Prevent Instantiation
private ThreadSafeSingleton() {
}
public static synchronized ThreadSafeSingleton getInstance() {
if (instance == null) {
instance = new ThreadSafeSingleton();
}
return instance;
}
}✅ Thread-safe ❌ Performance overhead
package com.designpatterns.singleton;
public class DoubleCheckedLockingSingleton {
// Volatile keyword is used for ensuring visibility of instance across threads
private static volatile DoubleCheckedLockingSingleton instance = null;
// Prevent Instantiation
private DoubleCheckedLockingSingleton() {
}
public static DoubleCheckedLockingSingleton getInstance() {
// First check (Non Synchronized) for Performance optimization
if (instance == null) {
// Synchronized on class object
synchronized (DoubleCheckedLockingSingleton.class) {
// Second check (Synchronized) for thread safety
if (instance == null) {
instance = new DoubleCheckedLockingSingleton();
}
}
}
return instance;
}
}✅ Thread-safe ✅ Lazy ✅ High performance
📌 volatile prevents instruction reordering
package com.designpatterns.singleton;
public class BillPughSingleton {
// Prevent Instantiation
private BillPughSingleton() {
}
// static inner class
private static class Helper {
private static final BillPughSingleton INSTANCE = new BillPughSingleton();
}
public static BillPughSingleton getInstance() {
return Helper.INSTANCE;
}
}✅ Best balance ✅ Lazy + Thread-safe ✅ No synchronization
package com.designpatterns.singleton;
public enum EnumSingleton {
INSTANCE;
void doSomething() {
System.out.println("Hello World");
}
}✅ Thread-safe ✅ Serialization safe ✅ Reflection safe ❌ Less flexible
- Logger
- Configuration Manager
- Cache
- Thread Pool
- Database Connection Pool
- Spring Beans (default scope = singleton)
- Controlled access to sole instance
- Saves memory and resources
- Centralized state management
- Global mutable state
- Hard to test and mock
- Tight coupling
- Can hide dependencies
void breakSingletonUsingReflection() throws Exception {
// With the help of reflection we are accessing the private constructor
Constructor<Singleton> constructors = Singleton.class.getDeclaredConstructor();
// Making the private constructor accessible
constructors.setAccessible(true);
// Creating a new instance of Singleton using Singleton class itself
// and using reflection
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = constructors.newInstance();
// The hashcode of both the instances will be different
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
System.out.println(instance2.equals(instance1)); // false
}
✅ Fix:
We can use an boolean flag to which will be set to true when the instance is created. If the flag is already set, we will not create a new instance.static void breakSingletonUsingSerialization() throws Exception {
Singleton instance1 = Singleton.getInstance();
// Serializing the instance
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file"));
oos.writeObject(instance1);
oos.close();
// Deserializing the instance
ObjectInputStream ooi = new ObjectInputStream(new FileInputStream("file"));
Singleton instance2 = (Singleton) ooi.readObject();
ooi.close();
// The hashcode of both the instances will be different
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
System.out.println(instance2.equals(instance1)); // false
}✅ Fix: Singleton should implement Serializable interface and override readResolve() method. to return the same instance and it will prevent the singleton pattern from being broken using deserialization.
- Exactly one instance is required
- The object represents a shared system-wide resource
- You need controlled access to that instance
- Object creation is expensive
- You need multiple instances in future
- Testing/mocking is important (Singletons make testing harder)
- The class holds mutable global state
- Dependency Injection can solve the problem better
📌 Overusing Singleton leads to hidden global state.
🧠 One-liner recall:
“Singleton restricts a class to one instance and provides global access to it.”
Articles
Videos
