Report this

What is the reason for this report?

Thread Safety in Java Singleton Classes

Published on August 3, 2022
Thread Safety in Java Singleton Classes

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.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author

Pankaj Kumar
Pankaj Kumar
Author
See author profile

Java and Python Developer for 20+ years, Open Source Enthusiast, Founder of https://www.askpython.com/, https://www.linuxfordevices.com/, and JournalDev.com (acquired by DigitalOcean). Passionate about writing technical articles and sharing knowledge with others. Love Java, Python, Unix and related technologies. Follow my X @PankajWebDev

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.

Still looking for an answer?

Was this helpful?

Example 3 is the traditional double check idiom for lazy initialization. The double check is badly broken in java before version 5. The example you have here is broken also because instance is not declared volatile. The best way is to extract the singleton code to a separate class which is guaranteed to be loaded only when the referring class is instantiated. For more information see item 71 in “Effective Java” (2nd edition) by Joshua Bloch. But you’d better avoid singletons completely.

- Erik van Oosten

you can avoid your extra if condition if you create instance described below, Once we declare static, it will refer the same object all the time package com.journaldev.designpatterns; public class ASingleton{ private static ASingleton instance= new ASingleton(); private ASingleton(){ } public static synchronized ASingleton getInstance(){ return instance; } }

- Ben

',~ I am really thankful to this topic because it really gives useful information :-`

- Anonymous

double check lock is not thread safe in java this issue listed by PDM tool (block synchronizing)

- Hesham

there is a good way to implement the Singletons, that will look after all the issue and with lesser code public enum InputValidatorImpl { instance; // add some method }

- Rishi Dev Gupta

Hi Pankaj, I believe this is the best way, it doesn’t use any synchronization at all, provides better performance too. https://en.wikipedia.org/wiki/Initialization-on-demand\_holder\_idiom

- Asanka

String is not a very good candidate to be used in synchronization, so I have updated it with Object, learn more about synchronization and thread safety in java Why string is not good candidate… Since its immutable its a good candidate to use in synchronization block right.

- Naveen J

In your third approach, although it checks the value of instance once again within the synchronized block but the JIT compiler can rearrange the bytecode in a way that the reference to instance is set before the constructor has finished its execution. This means the method getInstance() returns an object that may not have been initialized completely. I think, the keyword volatile can be used for the instance variable. Variables that are marked as volatile get only visible to other threads once the constructor of the object has finished its execution completely.

- Archna Sharma

I think making instance volatile make much difference than approach given in post

- Amey Jadiye

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.
Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.