Singleton Pattern in Java
The Singleton Pattern
The Singleton Pattern ensures that a class has only one instance and provides a global point of access to it. It’s one of the most commonly used design patterns in Java.
☝️ Why Use Singleton?
- To control access to resources (e.g., configuration, logging, DB connections)
- Ensures consistency with a single shared instance
- Reduces memory footprint when a single object is reused
✅ Ways to Implement Singleton in Java
🔹 1. Eager Initialization
Instance is created at the time of class loading.
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {} // private constructor
public static Singleton getInstance() {
return instance;
}
}
Pros: Simple, thread-safe
Cons: Instance created even if not used
🔹 2. Lazy Initialization (Non-thread-safe)
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Pros: Instance created only when needed
Cons: Not thread-safe
🔹 3. Thread-safe Lazy Initialization (Synchronized)
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Pros: Thread-safe
Cons: Slight performance hit due to synchronized method
🔹 4. Double-Checked Locking with Volatile (Best of Both Worlds)
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
Pros: High performance, lazy loaded, thread-safe
Recommended for most use cases
🔹 5. Bill Pugh Singleton (Using Static Inner Class)
public class Singleton {
private Singleton() {}
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
Pros: Thread-safe, lazy initialization, no synchronization overhead
Very efficient and widely recommended
🔹 6. Enum Singleton (Best Practice)
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("Doing something...");
}
}
Pros: Thread-safe, protects against serialization & reflection attacks
Cons: Not suitable if your singleton must extend a class
✅ Summary of Approaches
Approach | Thread-safe | Lazy | Recommended |
---|---|---|---|
Eager Initialization | ✔️ | ❌ | Simple cases |
Lazy Initialization | ❌ | ✔️ | ❌ Not safe |
Synchronized Method | ✔️ | ✔️ | Okay |
Double-Checked Locking | ✔️ | ✔️ | 👍 Yes |
Static Inner Class | ✔️ | ✔️ | 👍 Yes |
Enum | ✔️ | ✔️ | 👍 Best practice |