Java Language – 79 – Singleton

Design Patterns – Singleton
Introduction to the Singleton Pattern

The Singleton pattern is one of the most commonly used design patterns in Java. It ensures that a class has only one instance and provides a global point of access to that instance. This pattern is particularly useful when exactly one object is needed to coordinate actions across the system, such as a configuration manager, thread pool, or database connection.

Why Use the Singleton Pattern?

The Singleton pattern offers several advantages:

  • Global Access: It provides a single point of access to the instance, making it easy to manage and share the same instance across different parts of the application.
  • Lazily Initialized: The Singleton is created only when it is first accessed, which can save resources in applications where the Singleton instance might not always be needed.
  • Thread-Safe: When implemented correctly, the Singleton pattern can ensure that the instance is thread-safe, avoiding race conditions.
Implementing the Singleton Pattern

There are various ways to implement the Singleton pattern in Java. One of the most common approaches is the lazy initialization method, which creates the Singleton instance only when it’s first requested. Here’s an example of how to implement the Singleton pattern in Java:


public class Singleton {
    // Private instance variable
    private static Singleton instance;

    // Private constructor to prevent instantiation
    private Singleton() {
    }

    // Global point of access to the Singleton instance
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    // Other methods and data members can be added here
}
Thread Safety in Singleton

One of the key considerations when implementing the Singleton pattern is ensuring thread safety. In the example above, the Singleton is not inherently thread-safe. In a multi-threaded environment, multiple threads may enter the getInstance method simultaneously and create multiple instances of the Singleton. To make it thread-safe, you can use synchronization or use the Bill Pugh Singleton pattern or an Enum to guarantee a single instance.

Bill Pugh Singleton

The Bill Pugh Singleton, also known as the “Initialization-on-demand holder idiom,” is a popular approach that combines lazy initialization with the safety of static inner classes. This ensures that the Singleton instance is created only when it is first accessed and is thread-safe. Here’s an example of the Bill Pugh Singleton:


public class BillPughSingleton {
    // Private constructor
    private BillPughSingleton() {
    }

    // Nested static class that holds the Singleton instance
    private static class SingletonHelper {
        private static final BillPughSingleton instance = new BillPughSingleton();
    }

    // Global point of access to the Singleton instance
    public static BillPughSingleton getInstance() {
        return SingletonHelper.instance;
    }

    // Other methods and data members can be added here
}
Conclusion

The Singleton pattern is a fundamental design pattern in Java that ensures a class has only one instance and provides global access to that instance. It is widely used to manage shared resources, configurations, and services in a centralized manner. When implementing the Singleton pattern, it is crucial to consider thread safety to prevent multiple instances from being created in a multi-threaded environment. The Bill Pugh Singleton and Enum Singleton are recommended solutions for achieving thread-safe singletons.