0

I bumped into this code on Wikipedia for a Singleton pattern. Can anyone explain the purpose/logic of checking for null twice?

public class SingletonDemo {
    private static volatile SingletonDemo instance = null;

    private SingletonDemo() {       }

    public static SingletonDemo getInstance() {
            if (instance == null) {
                    synchronized (SingletonDemo .class){
                            if (instance == null) {
                                    instance = new SingletonDemo ();
                            }
                  }
            }
            return instance;
    }
  }
Crocodile
  • 5,724
  • 11
  • 41
  • 67
  • 1
    I believe [this post will](http://stackoverflow.com/questions/15498654/java-is-there-any-reason-to-check-if-a-singleton-is-null-twice) answer your question. – icanc Apr 14 '13 at 03:57

5 Answers5

2

A quote from your Wikipedia link:

This method uses double-checked locking

http://en.wikipedia.org/wiki/Double_checked_locking_pattern#Usage_in_Java

drzymala
  • 2,009
  • 20
  • 26
1

Better to use inner class for Lazy Initialization than "double-checked locking":

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 { 
    private static final Singleton INSTANCE = new Singleton();
  }

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

double-checked locking is not foolproof. Static inner class is guaranteed by JVM to create thread-safe Singleton class lazily.

anubhava
  • 761,203
  • 64
  • 569
  • 643
  • You mean "better" as faster/more efficient or just better practice?? Would you mind explaining? – Crocodile Apr 14 '13 at 04:11
  • 1
    Better in terms of efficiency since even "double-checked locking" is not foolproof. Static inner class is guaranteed by JVM to create thread-safe SIngleton class lazily. – anubhava Apr 14 '13 at 04:13
  • @anubhava, may be you were wrong, according to this link http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html double-checked locking issue was fixed using volatile – Suganthan Madhavan Pillai May 30 '15 at 03:37
  • That was not the question here besides there are pitfalls in using volatile approach also. – anubhava May 30 '15 at 05:46
  • @anubhava Can you explain the pitfalls even with volatile or can just share the link to that question which has this stuff? – Akhil Dad Nov 27 '15 at 00:12
  • @AkhilDad: volatile does not solve the issue of atomicity, [check this Q&A](http://stackoverflow.com/questions/15077910/singleton-with-volatile-in-java) – anubhava Nov 27 '15 at 02:27
0

Lets say there are 2 Threads T1 and T2 calling the same method.

Now T1 went thru the 1st check and found that the instance is null, and then went to sleep. Lets say T2 kicks in (may not happen all the time, but sure will some of the time), and goes thru the 1st check and finds that the object is null, acquires the lock and creates the object.

Now T1 wakes up and gets the lock. At this point, if we don't check for null again, T1 will never know that there is a object created by T2 already. Hence the double check.

You might now ask, why not do the sync and null check at the beginning itself? If we sync all the time to check for null, that would make the method accessible to a single thread at a time, and cause a performance issue, at a cost of what? Just to have some efficiency at the beginning of the program, when there are just 2 or 3 threads trying to create that instance.

Pradeep Pati
  • 5,779
  • 3
  • 29
  • 43
0

More than one thread might invoke getInstance when instance is still null.

Only one thread will enter the synchronized block(lets say T1), others will wait.

When T1 will exit the synchronized block, some other thread will enter.

Then if there will no if (instance == null), new instance of Singleton will be created.

Grisha Weintraub
  • 7,803
  • 1
  • 25
  • 45
0

This code is assuming concurrency (more than one thread using the class at the same time).

The code first tries to see if there is an instance. If there is not, then tries to create one. To avoid another threads to do it at the same time it is doing it, it blocks the code with synchronized.

Now, between the first if (instance == null) and the synchronized, another faster thread might have squeezed in and created the instance, so the code checks again just to make sure.

cockypup
  • 1,013
  • 1
  • 10
  • 24