Asked  7 Months ago    Answers:  5   Viewed   37 times

From Head First design patterns book, the singleton pattern with double checked locking has been implemented as below:

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

I don't understand why volatile is being used. Doesn't volatile usage defeat the purpose of using double checked locking i.e performance?

 Answers

32

A good resource for understanding why volatile is needed comes from the JCIP book. Wikipedia has a decent explanation of that material as well.

The real problem is that Thread A may assign a memory space for instance before it is finished constructing instance. Thread B will see that assignment and try to use it. This results in Thread B failing because it is using a partially constructed version of instance.

Tuesday, June 1, 2021
 
SubniC
answered 7 Months ago
47

No, since you are obtaining lock on the SearchBox.class, only one thread will enter the synchronized block at a time. So the first thread enters then finds searchBox is null and creates it and then leaves the synchronized block, then the second thread enter the block then it finds that the searchBox is not null because the first thread already created it so it will not create a new instance of searchBox.

The double checked pattern is used to avoid obtaining the lock every time the code is executed. If the call are not happening together then the first condition will fail and the code execution will not execute the locking thus saving resources.

Sunday, June 6, 2021
 
Shobit
answered 6 Months ago
43

There's a good talk by the C++ committee language evolution chair on why.

Brief summary, many of the places that volatile is being removed from didn't have any understandable meaning and just caused confusion.


Some examples from the talk:

  • Volatile bit Fields should be specified by your hardware manual and/or compiler.
  • Is += a single/atomic instruction? How about ++?
  • How many reads/writes are needed for compare_exchange? What if it fails?
  • What does void foo(int volatile n) mean? or int volatile foo()
  • Should *vp; do a load? (This has changed twice in the standard.)
Thursday, July 29, 2021
 
scessor
answered 5 Months ago
63

Well, the only advantage that comes to my mind is (the illusion of) performance: check in a non-thread-safe way, then do some locking operations to check the variable, which may be expensive. However, since double checked locking is broken in a way that precludes any firm conclusions from the non-thread-safe check, and it always smacked of premature optimization to me anyway, I would claim no, no advantage - it is an outdated pre-Java-days idiom - but would love to be corrected.

Edit: to be clear(er), I believe double checked locking is an idiom that evolved as a performance enhancement on locking and checking every time, and, roughly, is close to the same thing as a non-encapsulated compare-and-swap. I'm personally also a fan of encapsulating synchronized sections of code, though, so I think calling another operation to do the dirty work is better.

Thursday, September 30, 2021
 
Levente Kürti
answered 2 Months ago
23

No. The singleton pattern just means that a single instance is the only instance -- it does not mean "make everything statically accessible".

The singleton pattern gives you all the benefits of a "single instance", without sacrificing the ability to test and refactor your code.

Edit:

The point I'm trying to make is that there is a difference between how functionality should be consumed (which depends on context), and how functionality should be initialized.

It may be appropriate that in most cases your object will only ever have a single instance (for example, in your final production system). But there are also other contexts (like testing) that are made much more difficult if you force it to be the only choice.

Also, making something static has more significant implications than just "only one instance of my class should be accessible" -- which is usually the intention.

Further, in software I've worked on, the initialization and lifecycle of objects is often controlled by someone else (I'm talking about DI here) -- and making something static really doesn't help here.

Tuesday, November 23, 2021
 
Rick Sladkey
answered 2 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share