Java Singleton pattern thread-safe

Jane 114 Published: 10/21/2024

Java Singleton pattern thread-safe

The age-old problem of creating a Singleton class that is thread-safe! In this case, we'll explore how to create a thread-safe Singleton using Java.

What's the issue with traditional Singleton?

In traditional Singleton designs, the instance creation and synchronization are not thread-safe. This means that multiple threads can access the instance variable simultaneously, leading to unexpected results, such as:

Multiple instances created: Two or more threads may create separate instances of the class.

Inconsistent state: The instance's state might be inconsistent due to concurrent modifications.

How do we solve this?

To make the Singleton thread-safe, we'll implement a double-checked locking (DCL) approach, which ensures that only one instance is created and returned:

public class ThreadSafeSingleton {

private static volatile ThreadSafeSingleton instance = null;

// Private constructor to prevent instantiation

private ThreadSafeSingleton() {}

public static ThreadSafeSingleton getInstance() {

if (instance == null) { // Check once

synchronized (ThreadSafeSingleton.class) {

if (instance == null) { // Double-checked locking

instance = new ThreadSafeSingleton();

}

}

}

return instance;

}

}

Explanation:

The volatile keyword ensures that changes to the instance variable are immediately visible across threads. We use a double-checked locking mechanism to create the instance only once, even when multiple threads access the getInstance() method simultaneously.

Here's how it works:

Initially, instance is set to null. When the getInstance() method is called, it checks if the instance is already created (i.e., not null). If so, it returns the existing instance. If instance is still null, the method enters a synchronized block. Within this block, we re-check if instance is still null. This ensures that even if another thread has just set instance to a non-null value, our current thread will see it as null. Only then do we create the new instance and assign it to instance. We exit the synchronized block and return the created or already existing instance.

Benefits:

Thread safety: The Singleton is now guaranteed to be thread-safe. Efficient creation: The double-checked locking ensures that only one instance is created, even in high-concurrency scenarios. Simplified code: Compared to other thread-safe Singleton implementations, this approach requires minimal additional code and complexity.

In summary, by implementing a double-checked locking mechanism with the volatile keyword, we've successfully created a thread-safe Singleton class that ensures only one instance is created and returned, even in high-concurrency environments.

Java Singleton pattern hackerrank Solution

I'd be happy to provide the solution for the Java Singleton Pattern problem on HackerRank!

Problem Description:

Design a class Singleton that has a private constructor, and provides a public method getInstance() which returns the only instance of this class.

Constraints:

The getInstance() method should return the same instance every time it is called. No external class can instantiate an object of type Singleton. Only one instance of Singleton exists at any given time.

Solution Code:

public class Singleton {

// Step 1: Declare a private static variable to store the single instance

private static Singleton singleton = null;

// Step 2: Make the constructor private so that it cannot be instantiated from outside

private Singleton() {}

// Step 3: Provide a public method getInstance() which returns the single instance

public static Singleton getInstance() {

if (singleton == null) { // Check if the singleton is not yet created

synchronized (Singleton.class) { // Synchronize access to prevent multiple instances

if (singleton == null) { // Double-check to ensure thread-safety

singleton = new Singleton(); // Create and store the single instance

}

}

}

return singleton;

}

}

Explanation:

We declare a private static variable singleton to store the single instance of the class. The constructor is made private to prevent external classes from instantiating an object of type Singleton. The public method getInstance() checks if the singleton is not yet created and creates it if necessary.

Thread-Safety:

To ensure thread-safety, we use synchronization using the synchronized keyword on the class itself (Singleton.class). This ensures that only one thread can execute this code at a time, preventing multiple instances from being created simultaneously.

Double-Check Mechanism:

The double-check mechanism is used to ensure thread-safety. We first check if the singleton is null, and then synchronize access using synchronized. Even if multiple threads access the code simultaneously, only one will execute the code that creates the singleton instance, ensuring that only one instance is created.

Benefits:

This solution ensures that:

Only one instance of Singleton exists at any given time. The getInstance() method always returns the same instance. No external class can instantiate an object of type Singleton.

Feel free to test this code on HackerRank or anywhere else!