Double Checked Locking on Singleton Class in Java - TechDoko

Hot

Post Top Ad

Double Checked Locking on Singleton Class in Java

Singleton class is quite common among Java developers, but it poses many challenges to junior developers. One of the key challenge they face is how to keep Singleton class as Singleton? i.e. how to prevent multiple instances of a Singleton due to whatever reasons. Double checked locking of Singleton is a way to ensure only one instance of Singleton class is created through application life cycle. As name suggests, in double checked locking, code checks for an existing instance of Singleton class twice with and without locking to double ensure that no more than one instance of singleton gets created. By the way, it was broken before Java fixed its memory models issues in JDK 1.5.

Why you need Double checked Locking of Singleton Class?
One of the common scenario, where a Singleton class breaks its contracts is multi-threading. If you ask a beginner to write code for Singleton design pattern, there is good chance that he will come up with something like below :

private static Singleton _instance;
     public static Singleton getInstance() {
          if (_instance == null) {
               _instance = new Singleton();
          }
     return _instance;
}

and when you point out that this code will create multiple instances of Singleton class if called by more than one thread parallel, he would probably make this whole getInstance() method synchronized, as shown in our 2nd code example getInstanceTS() method.

Though it’s a thread-safe and solves issue of multiple instance, it's not very efficient. You need to bear cost of synchronization all the time you call this method, while synchronization is only needed on first class, when Singleton instance is created.

This will bring us to double checked locking pattern, where only critical section of code is locked. Programmer call it double checked locking because there are two checks for _instance == null, one without locking and other with locking (inside synchronized) block.

Here is how double checked locking looks like in Java :

public static Singleton getInstanceDC() {
          if (_instance == null) {
               // Single Checked
               synchronized (Singleton.class) {
                    if (_instance == null) {
                    // Double checked
                    _instance = new Singleton();
               }
          }
     }
     return _instance;
}

On surface this method looks perfect, as you only need to pay price for synchronized block one time, but it still broken, until you make _instance variable volatile.

Without volatile modifier it's possible for another thread in Java to see half initialized state of _instance variable, but with volatile variable guaranteeing happens-before relationship, all the write will happen on volatile _instance before any read of _instance variable.

This was not the case prior to Java 5, and that's why double checked locking was broken before. Now, with happens-before guarantee, you can safely assume that this will work.


That's all about double checked locking of Singleton class in Java.

No comments:

Post a Comment