0 votes
in Design Patterns by
How can you achieve thread-safe singleton patterns in Java?

1 Answer

0 votes
by
A thread-safe singleton class is created which helps in object initialization in the presence of multiple threads. It can be done using multiple ways:

Using Enums: Enums are the simplest means of creating a thread-safe singleton class in Java because the synchronization support is inherently done by Java itself. Enums are by default final and this also helps in preventing multiple initializations at the time of serialization.

   public enum ThreadSafeSingleton{

      SINGLETON_INSTANCE;

      public void display(){

          System.out.println("Thread-safe singleton Display");

      }

   }

   // The Singleton class methods can be invoked as below

   ThreadSafeSingleton.SINGLETON_INSTANCE.show();

Using Static Field Initialization: Thread-safe singleton can also be created by creating the instance at the time of class loading. This is achieved by making use of static fields as the Classloader guarantees that the instances are initialized during class loading and the instance is not visible until that has been fully created.

   public class ThreadSafeSingleton{

      private static final ThreadSafeSingleton INSTANCE = new ThreadSafeSingleton();

      private ThreadSafeSingleton(){ }

      public static ThreadSafeSingleton getInstance(){

          return INSTANCE;

      }

      public void display(){

          System.out.println("Thread-safe Singleon");

      }

   }

   ThreadSafeSingleton.getInstance().display();

But the disadvantage of this way is that the initialization cannot be done lazily and the getInstance() method is called even before any client can call.

Using synchronized keyword: We can make use of the synchronized keyword upon the getInstance method as shown below.

In this method, we can achieve lazy initialization, and also since we use synchronized keywords, the object initialization is thread-safe.

The only problem is that since the whole method is synchronized, the performance is impacted in the presence of multiple threads.

   public class ThreadSafeSingleton

   {

    // Creating private instance to make it accessible only by getInstance() method

    private static ThreadSafeSingleton instance;

    private ThreadSafeSingleton()

    {

      // Making constructor private so that objects cant be initialized outside the class

    }

    //synchronized getInstance method

    synchronized public static ThreadSafeSingleton getInstance(){

      if (this.instance == null)

      {

        // if instance is null, initialize

        this.instance = new ThreadSafeSingleton();

      }

      return this.instance;

    }

   }

Double-check locking: Here, we will be using a synchronized block of code within the getInstance method instead of making the whole method synchronized. This ensures that only a handful of threads have to wait only for the first time thereby not impacting the performance.

   public class ThreadSafeSingleton {

    // Creating private instance to make it accessible only by getInstance() method

    private static ThreadSafeSingleton instance;

    private ThreadSafeSingleton(){

      // Making constructor private so that objects cant be initialized outside the class

    }

    public static ThreadSafeSingleton getInstance(){

      if (instance == null){

        //synchronized block of code

        synchronized (ThreadSafeSingleton.class){

          if(instance==null)

          {

            // initialize only if instance is null

            instance = new ThreadSafeSingleton();

          }

        }

      }

      return instance;

    }

   }

Related questions

+1 vote
asked Oct 17, 2020 in JAVA by rahuljain1
0 votes
asked Aug 12, 2020 in Design Patterns by RShastri
...