You are here
Home > java > Core Java >

Singleton Class In Java With Examples: A Comprehensive Guide

Singleton Class In Java With ExamplesIn this article, we will explore the concept of Singleton class in Java, with different implementation techniques, their advantages and disadvantages, and provide various code examples to demonstrate their utilization.

In Java programming, the concept of Singleton class comes from the Singleton design pattern which is one of the most commonly used design patterns in Java. It comes under the category of creational design patterns and is used to ensure that a class has only one instance and provides a global point of access to that instance.

What is a Singleton class in Java?

A class that can have only one instance (object) at any given time during the runtime of an application. It provides a global point of access to this instance, allowing other classes to use its functionality without the need to instantiate it multiple times.

If we try to instantiate the Singleton class second time, the new variable also points to the previously created instance. Therefore, whatever modifications we do to any variable inside the class through any instance, affects the variable of the single instance created.

For example, Runtime class, Action Servlet, Service Locator are some of the Singleton classes. Private constructors and factory methods also comes under the example of the singleton class.

Why Use Singleton Classes?

Singleton classes are generally used in the following situations:

  1. Resource Pooling: We can use it if we want to share a single instance of a class across the entire application to save resources.
  2. Global Access: When we need a globally accessible object that maintains state information.
  3. Controlled Access: If we want to control the instantiation process to ensure that only one instance is created.

What is the primary purpose of creating a Singleton class?

The main objective of creating a Singleton class in Java is to restrict the creation of number of objects. Moreover, By using the Singleton class, the object would not be created each time a new request is made. Instead, a single object will be used repeatedly. Singleton pattern in Java is mostly used with multi-threaded and database applications. For example, we use the concept of singleton class while creating a database connection. In this case, we restrict the creation of multiple database connections to control the memory wastage.

How to create a Singleton class in Java?

Creating a Singleton class in Java involves certain steps to make sure that only one instance of the class is created and that instance is globally accessible. Below are the detailed steps to create a Singleton class in Java along with examples:

Step#1: Make the Constructor Private

First of all, declare the constructor of the Singleton class with the private keyword. By making constructor private, no other classes can instantiate or make objects from it. If there are multiple constructors in the class, make all of them private.

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

Step#2: Declare a Static Instance Variable

A private static instance variable of the same class that is the only instance of the class.

public class SingletonClass {
   
   private static SingletonClass instance; // Static instance variable
   
} 

Step#3: Provide a Static Method to Get the Instance

Declare a static method with the return type as an object of this singleton class.

public class SingletonClass {

   public static SingletonClass getInstance() {
      if (instance == null) {
        instance = new SingletonClass ();
      }
      return instance;
   }
}

Complete Example of a Singleton Class

public class SingletonClass {

   private static SingletonClass instance; // Static instance variable

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

   public static SingletonClass getInstance() {
      if (instance == null) {
        instance = new SingletonClass ();
      }
      return instance;
   }
}

Example Usage

public class SingletonTest {
   
   public static void main(String[] args) {
   // Get the singleton instance
      SingletonClass singleton1 = SingletonClass.getInstance();
      SingletonClass singleton2 = SingletonClass.getInstance();

   // Check if both instances are the same
      System.out.println(singleton1 == singleton2); // Output: true
   }
}

In the above example usage, we make the constructor private to prevent the class from being instantiated directly from outside the class. We declare a static instance variable that holds the single instance of the class. We provide a static method getInstance() that checks if the instance is null (i.e., if it has not been initialized yet). If it is null, it creates a new instance; otherwise, it returns the existing instance.

When we use getInstance() method, we can make sure that our class behaves as a Singleton in Java, with only one instance available throughout the JVM.

Note: For thread-safe implementations, it is recommended to use techniques such as double-checked locking. We need to be extra cautious when using singletons in multithreaded environments to avoid potential race conditions and synchronization issues.

Singleton Class In Java Using Bill Pugh’s Method

Bill Pugh’s Singleton, also known as the Initialization on Demand Holder (IODH), is a thread-safe and efficient way to implement the Singleton class in Java. This pattern uses a static inner class to hold the Singleton instance and initializes it on demand, ensuring lazy initialization.

As shown in the example below, the private constructor prevents instantiation of the Singleton class from outside. When the getInstance() method is called for the first time, the Singleton instance is created within the static inner class, ensuring thread safety and efficient lazy initialization.

public class BillPughSingleton {

    // Private constructor to prevent instantiation from outside
    private BillPughSingleton() {}

    // Static inner class to hold the Singleton instance
    private static class SingletonHolder {
    
    // Initialize Singleton instance on demand
         private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }

    // Public method to access the Singleton instance
    public static BillPughSingleton getInstance() {
       return SingletonHolder.INSTANCE;
    }

    // Other methods and properties of the Singleton class
    public void doSomething() {
       System.out.println("Bill Pugh's Singleton instance is doing something.");
    }
}

Bill Pugh’s Singleton pattern is commonly used in Java for its simplicity, thread safety, and efficient lazy initialization.

Singleton Class In Java Using Enum

Enum Singleton is another approach to implementing the Singleton pattern using enums in Java. In this approach, the Singleton instance is declared as an enum constant, and enums ensure that only one instance of the enum value exists, making it inherently thread-safe. Enum values are initialized statically when the enum class is loaded, ensuring eager initialization of the Singleton instance.

public enum EnumSingleton {

    // Singleton instance
    INSTANCE;

    // Other methods and properties of the Singleton class
    public void doSomething() {
        System.out.println("Enum Singleton instance is doing something.");
    }
}

Enum Singleton provides serialization and deserialization safety out of the box, ensuring that only one instance is maintained even after serialization and deserialization. Although Enum Singleton provides simplicity and thread safety, but it has some limitations in flexibility. Enums cannot be subclassed or instantiated, restricting the Singleton class from having subclasses or multiple instances.

In summary, both Bill Pugh’s Singleton and Enum Singleton are valid approaches to implementing the Singleton class in Java, each with its own set of advantages and disadvantages. Bill Pugh’s Singleton offers lazy initialization and flexibility, while Enum Singleton provides simplicity, thread safety, and automatic serialization handling. The choice between them depends on the specific requirements and constraints of the application.

Advantages of Singleton Class

  • Resource Effectiveness: Saves resources by reusing the same instance.
  • Global Access of the Instance: Provides a global point of access to the instance.
  • Thread Safety: Can be implemented to ensure safe concurrent access.

Disadvantages of Singleton Class

  • Difficulty in Testing: Singleton classes can be difficult to test due to their global state.
  • Possibility of Tight Coupling: Can lead to tight coupling between classes.
  • Potential for Excessive use: Excessive use of singletons can lead to poor design and maintainability issues.

FAQ

How do we ensure thread safety in a Singleton class?

To ensure thread safety in a Singleton class, we can use synchronization techniques such as double-checked locking or synchronized methods. Or else, we can use the Bill Pugh Singleton pattern, which leverages the initialization-on-demand holder idiom to ensure thread safety without the need for explicit synchronization.

Can we subclass a Singleton class in Java?

Yes, it is technically feasible to subclass a Singleton class in Java, but it is generally not recommended as it can lead to unexpected behavior and violate the Singleton pattern’s purpose of having only one instance of the class.

Are Singleton classes thread-safe by default?

No, Singleton classes are not thread-safe by default. Singleton classes may or may not be thread-safe. It depends on the implementation technique we use. It’s important to consider thread safety when designing and implementing a Singleton class, particularly in multi-threaded environments.

Is it possible to serialize a Singleton class in Java?

Yes, it is possible to serialize a Singleton class in Java. However, we should take special care to ensure that the Singleton feature is maintained during deserialization. This can be achieved by implementing the readResolve() method to return the existing instance during deserialization.

When should we avoid using a Singleton class in Java?

Although Singleton classes offer numerous benefits, but they may not be relevant for every scenario. We should avoid using Singleton classes when:

  • There is no requirement for a single instance throughout the application’s lifecycle.
  • Global state may introduce unnecessary complexity or tight coupling between components.
  • Alternatively, dependency injection frameworks can offer more flexibility and testability.

Conclusion

In this article, we explored the significance of Singleton class, its implementation technique, its advantages, disadvantages and some FAQs. With this knowledge and ample code examples, you can utilize the Singleton class to build robust and productive Java applications. So, the next time when you encounter a scenario where you need to ensure only one instance of a class, think of using the Singleton class in Java as your favorite solution.

Leave a Reply


Top