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)