Home > Tutorials > Architecture

Thread safe singleton design pattern example

Last updated : 14 May 2022

The important concept behind the singleton design pattern is to have no more than one instance of the target class at any given time per java virtual machine. This involves some minor modifications to our regular java class that we intend to convert to a singleton class.

When to use singleton class?

The concept of the Singleton pattern has always been a debatable topic. My in-depth research reveals that there are actually very few acceptable reasons to use a singleton class. In most use cases, the framework you use most likely have an out of the box solution in place. Some examples are logging, cache, configuration, and database connection pools that provide a global point of access to that instance throughout the application.

Implementation of the singleton class

When implementing a singleton class, we have to place certain restrictions on instantiating objects from our singleton class.

The caller is not allowed to instantiate the object by calling the new operator. This direct instantiation is defeated by providing a private constructor, disallowing the use of new outside the class.

public class Singleton {
   private static Singleton instance = null;
   private Singleton() {
   }
   public static Singleton getInstance() {
      if(instance == null) {
         instance = new Singleton();
      }
      return instance;
   }
}

To get the instance of the class, we call the static method getInstance(). This method is made static since we should be able to call it without creating an object of our singleton class. When first calling this static method, an instance of the Singleton class is created, assigned to a private static Singleton instance, and returned. Every subsequent call to the method will return the same object. The Singleton instance variable is also made static to allow static method getInstance() to access it.

Is singleton thread safe?

A singleton class itself is not thread safe. Multiple threads can access the singleton same time and create multiple objects, violating the singleton concept. The singleton may also return a reference to a partially initialized object.

How to make a singleton thread-safe?

The short answer is a singleton can be made thread-safe by instantiating the singleton class inside a static inner class or static initializer block. If you analyze the above code carefully, you will notice some thread safety issues when multiple threads try to access our singleton. To prevent concurrent multi-threaded access, each thread must obtain a lock to access getInstance() method. The problems we face are:

  • Multiple threads can access getInstance() and create objects same time, leading to multiple objects.
  • A thread may get a reference to a partially initialized object.

2 Ways to implement a thread safe singleton class in java

  1. Using static inner class
  2. Using static initializer block

Using static inner class

If you are looking for a thread-safe version of singleton, the below listed code achieves it by implementing a static inner class. It does thread-safe lazy-initialization of the object without explicit synchronization. Note that the variable INSTANCE is wrapped in an inner class, utilizing the class loader to do synchronization. The class loader guarantees to complete all static initialization before it grants access to the class. This implementation lazy initializes the INSTANCE by calling LoadSingleton.INSTANCE when first accessed inside getInstance() method.

public class Singleton {
private static class LoadSingleton {
      static final Singleton INSTANCE = new Singleton();
   }
   private Singleton() {}

   public static Singleton getInstance() {
      return LoadSingleton.INSTANCE;
   }
}

Using static initializer block

The below code illustrates how to implement a thread safe singleton class in java using static initializer block. The only difference is the way the instance is created. Static initializer block vs static inner class.

public class Singleton { 
private final static Singleton instance; 
   static { 
	instance = new Singleton(); 
   } 
   private Singleton() {} 
   public static Singleton getInstance() { 
	return instance; 
   } 
}
Lance
By: Lance
Lance is a software engineer with over 15 years of experience in full-stack software development.
Read more...

Comments are disabled

No Comments