How do you create a thread-safe singleton in Java?

Creating a Thread-Safe Singleton in Java Using Double-Checked Locking

The Singleton Design Pattern is a commonly used design pattern in Java that restricts the instantiation of a class to a single instance. However, ensuring thread safety in a Singleton class can be challenging, especially when the Singleton class is being accessed by multiple threads concurrently.

A thread-safe Singleton ensures that only one instance of the singleton class is created even when multiple threads are trying to create an instance of the singleton class concurrently.

The correct means of creating a thread-safe singleton in Java is by employing Double-Checked Locking.

What is Double-checked Locking?

Double-Checked Locking is a programming technique used in software development to reduce the overhead of acquiring a lock by testing the locking criterion (the 'lock hint') before actually acquiring the lock.

In a multi-threaded environment, here is how Double-Checked Locking works:

  • Firstly, check if an instance of the Singleton class is created. If not, then synchronize this block.
  • Once a thread is inside the synchronized block, it again checks whether there's another instance existing or not.

This approach of double checking significantly reduces the use and overhead of synchronization, making the code more efficient.

Converting a Singleton Class to Thread-Safe Singleton

Here is a simple thread-safe Singleton class using Double-Checked Locking:

public class Singleton {
  private volatile static Singleton uniqueInstance;

  private Singleton() {}

  public static Singleton getInstance() {
    if (uniqueInstance == null) {
      synchronized (Singleton.class) {
        if (uniqueInstance == null) {
          uniqueInstance = new Singleton();
        }
      }
    }
    return uniqueInstance;
  }
}

In the above code, the keyword 'volatile' ensures that multiple threads handle the uniqueInstance variable correctly whenever it is being initialized to the Singleton instance.

It should be noted that Thread-Safe Singleton using Double-Checked Locking should be used only if the Singleton class is heavy and requires a lot of resources.

While Double-Checked Locking might appear complex at first, it's a crucial tool in making sure your Singleton is thread-safe and efficient in a multi-threaded environment.

Do you find this helpful?