Singleton Design Pattern in Java with Real Examples and Thread Safety

The Singleton Design Pattern is one of the most widely used and frequently asked design patterns in Java interviews. It ensures that only one instance of a class exists throughout the application lifecycle and provides a global access point to that instance.


The Singleton Pattern belongs to the Creational Design Patterns category because it controls how objects are created.


What is Singleton Design Pattern?

Singleton is a design pattern that restricts object creation to exactly one instance.

Instead of allowing multiple objects to be created, the class manages its own instance internally and exposes a method to access it.


Why Do We Need Singleton Pattern?

Some resources should exist only once in an application. Creating multiple instances may waste memory or cause inconsistent behaviour.

Examples

  • Database Connection Manager
  • Configuration Manager
  • Logging Service
  • Cache Manager
  • Thread Pool Manager

Problem Without Singleton


DatabaseConfig config1 =
        new DatabaseConfig();

DatabaseConfig config2 =
        new DatabaseConfig();

The application creates two separate objects. Sometimes this behaviour is undesirable.


Basic Singleton Implementation


public class Singleton {

    private static Singleton instance =
            new Singleton();

    private Singleton() {

    }

    public static Singleton getInstance() {

        return instance;

    }
}

The constructor is private, preventing direct object creation.


Using Singleton


Singleton s1 =
        Singleton.getInstance();

Singleton s2 =
        Singleton.getInstance();

System.out.println(s1 == s2);

Output


true

Both references point to the same object.


How Singleton Works Internally

The Singleton class creates an object internally and stores it in a static variable.

Whenever getInstance() is called, the same object is returned.



Application
      |
      v
getInstance()
      |
      v
Single Object

Lazy Initialization Singleton

In Eager Initialization, the object is created immediately. Sometimes we want to create the object only when it is first needed.



public class Singleton {

    private static Singleton instance;

    private Singleton() {

    }

    public static Singleton getInstance() {

        if(instance == null) {

            instance =
                new Singleton();

        }

        return instance;
    }
}

This approach is called Lazy Initialization.


Problem With Lazy Initialization

The previous implementation is not thread-safe.

If two threads call getInstance() simultaneously, multiple objects may be created.


Thread Safe Singleton


public class Singleton {

    private static Singleton instance;

    private Singleton() {

    }

    public static synchronized
        Singleton getInstance() {

        if(instance == null) {

            instance =
                new Singleton();

        }

        return instance;
    }
}

The synchronized keyword prevents simultaneous object creation.


Drawback of Synchronized Method

Synchronization solves the problem but may reduce performance because every call requires locking.


Double Checked Locking

A more efficient solution is Double Checked Locking.



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;
    }
}

This approach provides thread safety while minimizing synchronization overhead.


Bill Pugh Singleton

One of the most recommended Singleton implementations is the Bill Pugh approach.



public class Singleton {

    private Singleton() {

    }

    private static class Holder {

        private static final
            Singleton INSTANCE =
                new Singleton();

    }

    public static Singleton
        getInstance() {

        return Holder.INSTANCE;

    }
}

This implementation is thread-safe, efficient and lazy-loaded.


Enum Singleton

Java provides an elegant approach using enums.



public enum Singleton {

    INSTANCE;

}

Joshua Bloch recommends Enum Singleton because it protects against reflection and serialization issues.


Real World Example

Consider a logging system.



public class Logger {

    private static final
        Logger INSTANCE =
            new Logger();

    private Logger() {

    }

    public static Logger
        getInstance() {

        return INSTANCE;

    }
}

All modules use the same Logger instance.


Advantages of Singleton Pattern

  • Controlled object creation
  • Global access point
  • Memory efficient
  • Useful for shared resources
  • Easy to implement

Disadvantages of Singleton Pattern

  • Can introduce global state
  • Difficult unit testing
  • Tight coupling risks
  • Can violate Single Responsibility Principle

Singleton vs Spring Singleton Bean

Java Singleton Spring Singleton
One Object Per JVM One Bean Per Container
Managed By Class Managed By Spring
Manual Implementation Framework Managed

This difference is frequently asked in Spring interviews.


Common Interview Questions

What is Singleton Design Pattern?

A design pattern that ensures only one object instance exists.


Why make constructor private?

To prevent external object creation using the new keyword.


Is Singleton thread-safe by default?

No. Thread safety depends on implementation.


Which Singleton implementation is preferred?

Bill Pugh Singleton and Enum Singleton are commonly recommended.


Can Singleton be broken?

Yes. Reflection, serialization and cloning can break Singleton implementations if not handled properly.


Best Practices

  • Use Singleton only when a single instance is truly required.
  • Prefer Bill Pugh implementation for most applications.
  • Consider Enum Singleton when appropriate.
  • Avoid excessive use of global state.
  • Evaluate whether Spring can manage the object instead.

Frequently Asked Questions (FAQ)

Can Singleton improve performance?

Yes. It avoids repeated object creation for shared resources.


Can a Singleton class have multiple methods?

Yes. Singleton only restricts object creation, not functionality.


Does Spring use Singleton scope by default?

Yes. Singleton is the default bean scope in Spring Framework.


Conclusion

The Singleton Design Pattern is one of the most important design patterns in Java. Understanding Eager Initialization, Lazy Initialization, Thread-Safe Singleton, Double Checked Locking and Bill Pugh Singleton helps developers build efficient applications and perform well in Java interviews.


Keywords

Singleton Design Pattern, Singleton Pattern Java, Thread Safe Singleton, Bill Pugh Singleton, Java Design Patterns, Creational Design Patterns, Singleton Interview Questions, Double Checked Locking Java, Enum Singleton, Spring Singleton vs Java Singleton, OOP Design Patterns, Core Java Interview Questions, Singleton Example Java, Java Architecture, Software Design Patterns



Singleton Design Pattern in Java with Real Examples and Thread Safety Singleton Design Pattern in Java with Real Examples and Thread Safety Reviewed by 13thGhost on 2:20 AM Rating: 5

No comments:

Recommended Posts

Powered by Blogger.