DEV Community

Dev Cookies
Dev Cookies

Posted on

πŸ“ Day Three: Singleton Design Pattern in Java

πŸ” 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:

  1. Basic Singleton (Lazy Initialization)
  2. Thread-Safe Singleton (Synchronized)
  3. Bill Pugh Singleton (Best Practice)
  4. 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; } } 
Enter fullscreen mode Exit fullscreen mode

❌ 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; } } 
Enter fullscreen mode Exit fullscreen mode

βœ… 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; } } 
Enter fullscreen mode Exit fullscreen mode

βœ… 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"); } } 
Enter fullscreen mode Exit fullscreen mode

βœ… 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(); } } 
Enter fullscreen mode Exit fullscreen mode

πŸ§ͺ Output:

Same LazySingleton? true Same BillPughSingleton? true Doing something from Enum Singleton 
Enter fullscreen mode Exit fullscreen mode

βš™οΈ UML Diagram (Text Format)

 +--------------------+ | SingletonClass | +--------------------+ | -instance: static | | -constructor() | +--------------------+ | +getInstance(): SingletonClass | +--------------------+ 
Enter fullscreen mode Exit fullscreen mode

πŸ§‘β€πŸ« 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)