Tutorial

Thread Safety in Java Singleton Classes

Published on August 3, 2022
author

Pankaj

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(s)

Category:
Tutorial

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?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
December 27, 2010

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

JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
January 23, 2014

invoke Bill Pugh’s singleton pattern https://en.wikipedia.org/wiki/Initialization\_on\_demand\_holder\_idiom

- gaurav

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    January 4, 2011

    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

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    January 8, 2011

    Here you are creating the instance at the time of class loading… what if we are expecting some parameters like DB Connection URL, User, Password to be passed in the getInstance method so that it will be generic.

    - Pankaj

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      January 28, 2011

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

      - Anonymous

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        May 15, 2013

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

        - Hesham

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          July 19, 2013

          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

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          July 20, 2013

          there are several ways to implement singleton pattern and Enum is one of the way but we can’t achieve lazy initialization with this. Read more at https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-with-examples#enum-singleton

          - Pankaj

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            June 19, 2014

            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

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            June 19, 2014

            Singleton Pattern Approaches - read this article to learn about different ways and their pros-cons.

            - Pankaj

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              July 25, 2014

              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

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              July 26, 2014

              We should not use any object that is maintained in a constant pool, for example String should not be used for synchronization because if any other code is also locking on same String, it will try to acquire lock on the same reference object from String pool and even though both the codes are unrelated, they will lock each other.

              - Pankaj

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                February 19, 2015

                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

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  May 19, 2015

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

                  - Amey Jadiye

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    December 4, 2015

                    Very nice article. But if loop wording is not correct, please change it to if condition.

                    - Praful

                      JournalDev
                      DigitalOcean Employee
                      DigitalOcean Employee badge
                      February 3, 2016

                      Hi, Great article! I am trying t understand thread safety in Singleton Pttern. Can you please provide and example code where different threads are trying to implement Singleton pattern. Thanks, Divya

                      - DIVYA PALIWAL

                        JournalDev
                        DigitalOcean Employee
                        DigitalOcean Employee badge
                        February 9, 2016

                        That I really appreciate for this article . I learned good stuff today, and also I red some where below code snipped is very good code for singleton, can you compare with your code in terms pros and cons. package com.journaldev.designpatterns; public class ASingleton{ private ASingleton(){ } private static class ASingletonInnerClass{ private static final ASingleton ASINGLETON= new ASingleton(); } public static ASingleton getInstance(){ return ASingletonInnerClass.ASINGLETON; } }

                        - Ganesh

                          JournalDev
                          DigitalOcean Employee
                          DigitalOcean Employee badge
                          May 23, 2016

                          best to make getInstance() synchronized

                          - Satya

                          JournalDev
                          DigitalOcean Employee
                          DigitalOcean Employee badge
                          September 15, 2016

                          If the method is synchronized, where huge threads are calling that method, every thread will have to wait when it’s being used by other thread. Think is it really required when the object is already created and != null? So making method synchronization is not a good idea.

                          - Santosh Kumar Kar

                            JournalDev
                            DigitalOcean Employee
                            DigitalOcean Employee badge
                            December 23, 2016

                            You haven’t made any comment regarding why not making ‘instance’ volatile… any thoughts?

                            - Hamid Khan

                              JournalDev
                              DigitalOcean Employee
                              DigitalOcean Employee badge
                              February 2, 2017

                              Can we not use the volatile() instead of using synchroniation?

                              - Ravi

                                JournalDev
                                DigitalOcean Employee
                                DigitalOcean Employee badge
                                April 23, 2017

                                I replied the same answer to a interviewer but she asked me that object is not created yet since getInstance() is static method who will get object lock in synchronization. Thanks, Prachi

                                - Prachi

                                JournalDev
                                DigitalOcean Employee
                                DigitalOcean Employee badge
                                August 20, 2017

                                by object do you mean the mutex object??

                                - Nayanava

                                  JournalDev
                                  DigitalOcean Employee
                                  DigitalOcean Employee badge
                                  March 9, 2018

                                  Hi, Since mutex is static varible it will be initialized during class loading time, and then synchnozization happens on the lock of mutex object.

                                  - Raviraj_bk

                                    JournalDev
                                    DigitalOcean Employee
                                    DigitalOcean Employee badge
                                    April 24, 2017

                                    Thank you very much

                                    - jubi max

                                      JournalDev
                                      DigitalOcean Employee
                                      DigitalOcean Employee badge
                                      June 30, 2017

                                      Hi. I have two issues with the selection of the third option. One is that by creating a mutex static object you contradict the fact that you keep a static option that you may never use(mutex). Second is that i would change the code to contain the if condition one time unsynchronized and obe time in an inner if when it is synchronized on mutex.

                                      - Noy

                                      JournalDev
                                      DigitalOcean Employee
                                      DigitalOcean Employee badge
                                      December 15, 2017

                                      As “instance” field is static. So will it make sense to synchronize on (synchronized (ASingleton.class)

                                      - Aarati

                                        JournalDev
                                        DigitalOcean Employee
                                        DigitalOcean Employee badge
                                        November 17, 2017

                                        I think the 3rd approach is incorrect. instance variable should be volatile! like this: private static volatile ASingleton instance= null; -------- If instance variable is not volatile, JVM can reorder new ASingleton() and instance= operations which may result in an instance variable which will point to uninitialized memory! refer to: https://en.wikipedia.org/wiki/Double-checked\_locking

                                        - Marton Korosi

                                          JournalDev
                                          DigitalOcean Employee
                                          DigitalOcean Employee badge
                                          February 22, 2018

                                          I think that this kind of implementation doesn’t avoid the singleton creation through reflection. My favourite implementation is something like this: public class MySingleton { private static class Loader { private static MySingleton INSTANCE = new MySingleton(); } private MySingleton(){ if(Loader.INSTANCE!=null){ throw new InstantiationError( “Creating of this object is not allowed.” ); } } public static MySingleton getInstance(){ return MySingleton.Loader.INSTANCE; } } What do you think? Thanks Edo

                                          - Edo

                                            JournalDev
                                            DigitalOcean Employee
                                            DigitalOcean Employee badge
                                            March 9, 2018

                                            we can use "synchronized (ASingleton.class) " instead of below piece of code synchronized (mutex) { result = instance; if (result == null) instance = result = new ASingleton(); }

                                            - Raviraj_bk

                                              JournalDev
                                              DigitalOcean Employee
                                              DigitalOcean Employee badge
                                              March 27, 2018

                                              Thanks Pankaj, great article. One question: does adding synchronization at the getInstance level (regardless of the approach) remove the need to synchronize access to other resources in the instance (member variables, class variables and methods)? thanks again

                                              - Diego

                                                JournalDev
                                                DigitalOcean Employee
                                                DigitalOcean Employee badge
                                                April 9, 2018

                                                C++ implementation using a bool var instead (possibly more efficent) static ConnectionManager *_currentInstance = nullptr; static bool instanceAvailable = false; static std::mutex singletonMutex; ConnectionManager* ConnectionManager::getInstance() { // thread safe implementation of SINGLETON if (!instanceAvailable) { instanceAvailable = true; std::unique_lock lck(singletonMutex); if (!_currentInstance) { _currentInstance = new ConnectionManager; } } return _currentInstance; }

                                                - AB

                                                  JournalDev
                                                  DigitalOcean Employee
                                                  DigitalOcean Employee badge
                                                  April 29, 2018

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

                                                  - Parvesh Kumar

                                                    JournalDev
                                                    DigitalOcean Employee
                                                    DigitalOcean Employee badge
                                                    May 2, 2018

                                                    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

                                                      JournalDev
                                                      DigitalOcean Employee
                                                      DigitalOcean Employee badge
                                                      June 26, 2018

                                                      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

                                                        JournalDev
                                                        DigitalOcean Employee
                                                        DigitalOcean Employee badge
                                                        September 2, 2018

                                                        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

                                                          JournalDev
                                                          DigitalOcean Employee
                                                          DigitalOcean Employee badge
                                                          September 5, 2018

                                                          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

                                                            JournalDev
                                                            DigitalOcean Employee
                                                            DigitalOcean Employee badge
                                                            December 18, 2018

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

                                                            - Deepak

                                                              JournalDev
                                                              DigitalOcean Employee
                                                              DigitalOcean Employee badge
                                                              February 22, 2018

                                                              I think that this kind of implementation doesn’t avoid the singleton creation through reflection. My favourite implementation is something like this: public class MySingleton { private static class Loader { private static MySingleton INSTANCE = new MySingleton(); } private MySingleton(){ if(Loader.INSTANCE!=null){ throw new InstantiationError( “Creating of this object is not allowed.” ); } } public static MySingleton getInstance(){ return MySingleton.Loader.INSTANCE; } } What do you think? Thanks Edo

                                                              - Edo

                                                                JournalDev
                                                                DigitalOcean Employee
                                                                DigitalOcean Employee badge
                                                                March 9, 2018

                                                                we can use "synchronized (ASingleton.class) " instead of below piece of code synchronized (mutex) { result = instance; if (result == null) instance = result = new ASingleton(); }

                                                                - Raviraj_bk

                                                                  JournalDev
                                                                  DigitalOcean Employee
                                                                  DigitalOcean Employee badge
                                                                  March 27, 2018

                                                                  Thanks Pankaj, great article. One question: does adding synchronization at the getInstance level (regardless of the approach) remove the need to synchronize access to other resources in the instance (member variables, class variables and methods)? thanks again

                                                                  - Diego

                                                                    JournalDev
                                                                    DigitalOcean Employee
                                                                    DigitalOcean Employee badge
                                                                    April 9, 2018

                                                                    C++ implementation using a bool var instead (possibly more efficent) static ConnectionManager *_currentInstance = nullptr; static bool instanceAvailable = false; static std::mutex singletonMutex; ConnectionManager* ConnectionManager::getInstance() { // thread safe implementation of SINGLETON if (!instanceAvailable) { instanceAvailable = true; std::unique_lock lck(singletonMutex); if (!_currentInstance) { _currentInstance = new ConnectionManager; } } return _currentInstance; }

                                                                    - AB

                                                                      JournalDev
                                                                      DigitalOcean Employee
                                                                      DigitalOcean Employee badge
                                                                      April 29, 2018

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

                                                                      - Parvesh Kumar

                                                                        JournalDev
                                                                        DigitalOcean Employee
                                                                        DigitalOcean Employee badge
                                                                        May 2, 2018

                                                                        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

                                                                          JournalDev
                                                                          DigitalOcean Employee
                                                                          DigitalOcean Employee badge
                                                                          June 26, 2018

                                                                          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

                                                                            JournalDev
                                                                            DigitalOcean Employee
                                                                            DigitalOcean Employee badge
                                                                            September 2, 2018

                                                                            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

                                                                              JournalDev
                                                                              DigitalOcean Employee
                                                                              DigitalOcean Employee badge
                                                                              September 5, 2018

                                                                              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

                                                                                JournalDev
                                                                                DigitalOcean Employee
                                                                                DigitalOcean Employee badge
                                                                                December 18, 2018

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

                                                                                - Deepak

                                                                                  JournalDev
                                                                                  DigitalOcean Employee
                                                                                  DigitalOcean Employee badge
                                                                                  May 12, 2019

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

                                                                                  - Pallavi Singh

                                                                                    JournalDev
                                                                                    DigitalOcean Employee
                                                                                    DigitalOcean Employee badge
                                                                                    June 3, 2020

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

                                                                                    - Kshitiz Gupta

                                                                                      JournalDev
                                                                                      DigitalOcean Employee
                                                                                      DigitalOcean Employee badge
                                                                                      June 11, 2021

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

                                                                                      - Sagar Solanki

                                                                                        JournalDev
                                                                                        DigitalOcean Employee
                                                                                        DigitalOcean Employee badge
                                                                                        June 20, 2021

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

                                                                                        - sakshi

                                                                                          Try DigitalOcean for free

                                                                                          Click below to sign up and get $200 of credit to try our products over 60 days!

                                                                                          Sign up

                                                                                          Join the Tech Talk
                                                                                          Success! Thank you! Please check your email for further details.

                                                                                          Please complete your information!

                                                                                          Become a contributor for community

                                                                                          Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                                                                                          DigitalOcean Documentation

                                                                                          Full documentation for every DigitalOcean product.

                                                                                          Resources for startups and SMBs

                                                                                          The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                                                                                          Get our newsletter

                                                                                          Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                                                                                          New accounts only. By submitting your email you agree to our Privacy Policy

                                                                                          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.