// Tutorial //

Thread Safety in Java Singleton Classes

Published on August 3, 2022
Default avatar
By Pankaj
Developer and author at DigitalOcean.
Thread Safety in Java Singleton Classes

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Singleton is one of the most widely used creational design pattern to restrict the object created by applications. If you are using it in a multi-threaded environment, then the thread-safety of the singleton class is very important. In real-world applications, resources like Database connections or Enterprise Information Systems (EIS) are limited and should be used wisely to avoid any resource crunch. To achieve this, we can implement a Singleton design pattern. We can create a wrapper class for the resource and limit the number of objects created at runtime to one.

Thread Safe Singleton in Java

thread safe singleton in java In general, we follow the below steps to create a singleton class:

  1. Create the private constructor to avoid any new object creation with new operator.
  2. Declare a private static instance of the same class.
  3. Provide a public static method that will return the singleton class instance variable. If the variable is not initialized then initialize it or else simply return the instance variable.

Using the above steps I have created a singleton class that looks like below. ASingleton.java

package com.journaldev.designpatterns;

public class ASingleton {

	private static ASingleton instance = null;

	private ASingleton() {
	}

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

}

In the above code, the getInstance() method is not thread-safe. Multiple threads can access it at the same time. For the first few threads when the instance variable is not initialized, multiple threads can enter the if loop and create multiple instances. It will break our singleton implementation.

How to achieve thread-safety in Singleton Class?

There are three ways through which we can achieve thread safety.

  1. Create the instance variable at the time of class loading. Pros:
  • Thread safety without synchronization
  • Easy to implement

Cons:

  • Early creation of resource that might not be used in the application.
  • The client application can’t pass any argument, so we can’t reuse it. For example, having a generic singleton class for database connection where client application supplies database server properties.
  1. Synchronize the getInstance() method. Pros:
  • Thread safety is guaranteed.
  • Client application can pass parameters
  • Lazy initialization achieved

Cons:

  • Slow performance because of locking overhead.
  • Unnecessary synchronization that is not required once the instance variable is initialized.
  1. Use synchronized block inside the if loop and volatile variable Pros:
  • Thread safety is guaranteed
  • Client application can pass arguments
  • Lazy initialization achieved
  • Synchronization overhead is minimal and applicable only for first few threads when the variable is null.

Cons:

  • Extra if condition

Looking at all the three ways to achieve thread-safety, I think the third one is the best option. In that case, the modified class will look like this:

package com.journaldev.designpatterns;

public class ASingleton {

	private static volatile ASingleton instance;
	private static Object mutex = new Object();

	private ASingleton() {
	}

	public static ASingleton getInstance() {
		ASingleton result = instance;
		if (result == null) {
			synchronized (mutex) {
				result = instance;
				if (result == null)
					instance = result = new ASingleton();
			}
		}
		return result;
	}

}

The local variable result seems unnecessary. But, it’s there to improve the performance of our code. In cases where the instance is already initialized (most of the time), the volatile field is only accessed once (due to “return result;” instead of “return instance;”). This can improve the method’s overall performance by as much as 25 percent. If you think there are better ways to achieve this or if the thread-safety is compromised in the above implementation, please comment and share it with all of us.

Bonus Tip

String is not a very good candidate to be used with synchronized keyword. It’s because they are stored in a string pool and we don’t want to lock a string that might be getting used by another piece of code. So I am using an Object variable. Learn more about synchronization and thread safety in java.

You can checkout more Java examples from our GitHub Repository.


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Pankaj

author

Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?

Hi, I did not understood the use of result variable, and how it is helping in improve performance by 25%

- sakshi

    What is the use of mutex Object here sir i cannot understand.

    - Sagar Solanki

      I didn’t understand this part “Local variable result seems unnecessary” and the explanation you gave. Could you elaborate please?

      - Kshitiz Gupta

        Isn’t static inner helper class approach better than the above three mentioned?

        - Pallavi Singh

          Hi Pankaj, How to execute your Singleton class. Where is the main method ? Deepak

          - Deepak

            Hey Nice Solution but i think we can also optimize is by not creating object lock instead of it we can use class lock example Copied! package com.journaldev.designpatterns; public class ASingleton { private static volatile ASingleton instance; private ASingleton() { } public static ASingleton getInstance() { ASingleton result = instance; if (result == null) { synchronized (ASingleton.class) { result = instance; if (result == null) instance = result = new ASingleton(); } } return result; } } I am not sure Please guide me as i am fresher

            - Harshit Joshi

              This seems ok…create instance on class loading and later return same instance…No synchronization required. public class Singleton { private static Singleton singltonInstance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return singltonInstance; } @Override protected Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } }

              - Datta

                You don’t talk about enum. Enum objects are best suited for singleton classes. It covers both concurrency and serialization issues we face in our custom singleton classes.

                - jatin

                  public class TestSingleton { public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { ASingleton singleton1 = ASingleton.getInstance(); System.out.println(singleton1); ASingleton singleton2 = ASingleton.getInstance(); System.out.println(singleton2); Constructor c = ASingleton.class.getDeclaredConstructor((Class[]) null); c.setAccessible(true); System.out.println©; ASingleton singleton3 = c.newInstance((Object[]) null); System.out.println(singleton3); if (singleton1 == singleton2) { System.out.println(“Variable 1 and 2 referes same instance”); } else { System.out.println(“Variable 1 and 2 referes different instances”); } if (singleton1 == singleton3) { System.out.println(“Variable 1 and 3 referes same instance”); } else { System.out.println(“Variable 1 and 3 referes different instances”); } } } Hi Pankaj, NIce article, but the solution you provided , fails the above testcase. Thanks .

                  - ashish gupta

                    The third option is not a singlton class it will create new instance always.

                    - Parvesh Kumar