Friday, 29 December 2017

Thread-safe Singleton in Java using Double Checked Locking Idiom

Singleton Pattern is one of the famous design patterns from the Gang of Four. Even though nowadays it is considered as an anti-pattern, it has served us well in the past. In Singleton pattern, a class has just one instance throughout its lifetime and that instance is shared between multiple clients. Singleton class has two responsibility, first to ensure that only instance of the class gets created and second, provide a method getInstance() so that everyone can get access to that single instance i.e. global access. One of the issue, faced by Singelton design pattern in the multi-threading program is to ensure that just one instance of the class gets created, even if multiple clients called getInstance() method same time. Many programmers solved this problem by making whole getInstance() method synchronized, which results in poor performance because every time a thread enters a synchronization method, it acquires the lock and while it's been inside the method, no other thread are allowed to enter, even if they are not creating instance and just accessing already created instance.

Threadsafe Singleton using Double Checked Locking Idiom


Double checked locking idiom solves this problem by allowing you to eat your cake and have it as well, it ensures synchronization is used only when instance of Singleton is created, when getInstance() method is called first time and all other time, same instance is returned without any synchronization overhead. As the name suggests, it's double-checked, which means it checked two times whether _instnace (the singleton instance) is initialized or not, one without synchronization and other with synchronization. This double check ensures that locking is only used when an instance is null i.e. when first time someone calls getInstance(), all subsequent call will see _instnace not null hence they will not enter into synchronization block.

Here is the code of thread-safe singleton pattern using double-checked locking idiom:

/**
 * Thread Safe Singleton in Java using Double checked locking.
 * @author WINDOWS 8
 *
 */
public class Singleton {

    private static volatile Singleton _instance;

    /**
     * Double checked locking code on Singleton
     * @return Singelton instance
     */
    public static Singleton getInstance() {
        if (_instance == null) {
            synchronized (Singleton.class) {
                if (_instance == null) {
                    _instance = new Singleton();
                }
            }
        }
        return _instance;
    }

}

How Double Checked Locking Idiom Works


To illustrate the point, how this idiom prevents from two instances being created when two thread simultaneously calls the getInstance() method, let's see the theory. Suppose, thread T1 calls getInstance() very the first time and sees that _instance is null then it will go inside synchronization block and that point of time it paused. Now, thread T2 calls getInstance() and it will also see _instance variable null, but it cannot go inside synchronization block because the lock is held by Thread T1, which is inside the synchronization block. Now, thread T1 wake up and creates a new instance of singleton and come out of synchronized block.  After this when thread T2 goes inside synchronized block, it again checks whether _instance is null and this time check fails because _instnace is no more null. So thread T2 come out of the synchronized block without creating another instance.  Further calls to this method return from first check only.

By the way, double checked locking idiom was broken before Java 5. It was possible for a thread to see half initialized instance which will fail the first null check, resulting in returning a half-initialized Singleton. That's why it's absolutely critical to make _instnace a volatile variable. The Java memory model updates and happens-before makes double checked locking works again.

Oracle Java Guides, Oracle Java Tutorials and Materials, Oracle Java Certifications

That's all about how to create thread-safe Singleton in Java, but this is not the only way to create the thread-safe singleton. You can use Enum as Singleton then Java itself will guarantee that only one instance  will be created even in the case of multiple threads trying to access it the same time. Alternatively, you can also eagerly initialized the Singleton, in that case, it would be initialized on static initializer block at the time of class loading in a thread-safe manner.  If you decide to use double-checked locking idiom to make Singleton creation thread-safe, don't forget the volatile modifier.