A lock-free and faster approach to get Singleton instance

The traditional way of implementing Singleton design pattern is given in Listing 1. The implementing class provides a static method which instantiates it if no instance already exist. This method is synchronized to ensure that not more than one thread can concurrently execute it and thereby  create more than one instance of the class.

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

Listing 1. Traditional way of writing a Singleton class

In the above code, once a thread starts executing getInstance() it obtains a class level lock, blocking other threads from accessing the class. In this way, each thread while trying to get the singleton instance is blocking the other threads. Is this the intent of declaring getInstance() synchronized? No. The getInstance() method is synchronized to ensure that not more than one thread creates an instance of the class concurrently or in other words not more than one instances of this class are created in one JVM even if it is accessed by multiple threads concurrently. So, why should the getInstance() block threads from concurrently accessing the singleton instance?

A lock-free and faster approach of implementing Singleton design pattern is given below in Listing 2. The getInstance() in this implementation is not synchronized and it does not block other threads from concurrently accessing the singleton instance. The other threads are blocked only while trying to instantiate this class.

public class DBConnectionFactory {
      private static volatile DBConnectionFactory instance;
 
      private DBConnectionFactory() {
	    ...
      }
 
      public static DBConnectionFactory getInstance() {
	    if(instance == null) {
		  synchronized(DBConnectionFactory.class) {
			if(instance == null) {
			      instance = new DBConnectionFactory();
			}
		  }
            }
	    return instance;
      }
}

Listing 2. Lock-free and faster Singleton implementation

The double-checking of whether instance is null in Listing 2 is to ensure that only one instance of this class is created. It may happen that more than one threads concurrently evaluate the instance as null. So when any one of these threads obtain the class level lock by executing the synchronized block, it should be ensured again that no instance already exists before creating one.

The singleton instance is declared volatile to ensure that as soon as the instance is created by a thread within the synchronized block, it is immediately visible to other threads, even before the instantiating thread leaves the synchronized block.

While writing thread-safe programs, the synchronized blocks are preferred over synchronized methods for locking. The synchronized block should lock only the critical section of the code instead of locking the entire method. This approach reduces thread contention.

VN:F [1.9.18_1163]
Rating: 0.0/10 (0 votes cast)

Related posts:

  1. Writing Thread-Safe Programs – Analyze Cost Of Locking
  2. Writing Thread-Safe Programs Using ConcurrentHashMap
  3. A Partial-Blocking Thread-Safe Cache
  4. Applying Concurrency In Java
  5. Writing Thread-Safe Programs Using Atomic Variables
Author

About Madhura Oak

Madhura Oak is a Technical Leader at e-Zest Solutions Ltd. and has over 11 years of experience. She works on design and development of applications using Java EE, Spring, Hibernate and XML technologies.

  • Dstarh

    Might I also suggest the lazy, non synchronized thread safe method – ex then from java Wikipedia article on singletons

    public class Singleton {
    // Private constructor prevents instantiation from other classes
    private Singleton() { }

    /**
    * SingletonHolder is loaded on the first execution of Singleton.getInstance()
    * or the first access to SingletonHolder.INSTANCE, not before.
    */
    private static class SingletonHolder {
    public static final Singleton instance = new Singleton();
    }

    public static Singleton getInstance() {
    return SingletonHolder.instance;
    }
    }

    • http://www.e-zest.net/ Madhura Oak

      Hi, Thanks for your comment. The lazy initialization holder class idiom which you have mentioned is a simpler way to implement than the double-checked locking mentioned in the blog post. I just read in Effective Java that Initialization On Demand Holder is ideal for lazy initialization of a static field and the double-checked locking way with only volatile variable (instead of static volatile) should be used for lazy initialization of an instance field for better performance. Thanks once again!