π What is the Singleton Design Pattern?
The Singleton Pattern is a creational design pattern that ensures a class has only one instance and provides a global point of access to it.
β When Should You Use It?
- To manage shared resources like database connections, thread pools, caches, logging, etc.
- When you want to restrict object creation to only one instance throughout the application lifecycle.
π§ Real-World Analogy
Think of the President of a country. There is only one President at any given time. If anyone tries to create another one, it should return the same instance π.
π§± Structure
Weβll cover 4 variations of Singleton in Java:
- Basic Singleton (Lazy Initialization)
- Thread-Safe Singleton (Synchronized)
- Bill Pugh Singleton (Best Practice)
- Enum Singleton (Most Robust)
β 1. Lazy Initialization (Not Thread-Safe)
public class LazySingleton { private static LazySingleton instance; private LazySingleton() {} // private constructor public static LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; } }
β Not thread-safe. Two threads may create two instances.
β 2. Thread-Safe Singleton (Synchronized)
public class ThreadSafeSingleton { private static ThreadSafeSingleton instance; private ThreadSafeSingleton() {} public static synchronized ThreadSafeSingleton getInstance() { if (instance == null) { instance = new ThreadSafeSingleton(); } return instance; } }
β Thread-safe, but slower due to synchronization.
β 3. Bill Pugh Singleton (Recommended)
public class BillPughSingleton { private BillPughSingleton() {} private static class Holder { private static final BillPughSingleton INSTANCE = new BillPughSingleton(); } public static BillPughSingleton getInstance() { return Holder.INSTANCE; } }
β Thread-safe, fast, and lazy-loaded. Best practice in most cases.
β 4. Enum Singleton (Robust & Safe)
public enum EnumSingleton { INSTANCE; public void doSomething() { System.out.println("Doing something from Enum Singleton"); } }
β Simplest and safest, handles serialization, reflection, and thread safety.
π» Client Code
public class SingletonDemo { public static void main(String[] args) { LazySingleton s1 = LazySingleton.getInstance(); LazySingleton s2 = LazySingleton.getInstance(); System.out.println("Same LazySingleton? " + (s1 == s2)); // true BillPughSingleton b1 = BillPughSingleton.getInstance(); BillPughSingleton b2 = BillPughSingleton.getInstance(); System.out.println("Same BillPughSingleton? " + (b1 == b2)); // true EnumSingleton.INSTANCE.doSomething(); } }
π§ͺ Output:
Same LazySingleton? true Same BillPughSingleton? true Doing something from Enum Singleton
βοΈ UML Diagram (Text Format)
+--------------------+ | SingletonClass | +--------------------+ | -instance: static | | -constructor() | +--------------------+ | +getInstance(): SingletonClass | +--------------------+
π§βπ« Key Takeaways
- Singleton ensures only one instance exists.
- Use Bill Pugh or Enum versions in production.
- Useful for centralized services like logging, config, DB access.
π Up Next for Day 4: Want to explore Decorator, Strategy, or Adapter?
Let me know your pick, and Iβll keep the clean breakdown + rich Java code style coming!
Top comments (0)