the page at http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html says that double-checked locking is flawed in java. I'm just wondering does it also apply to other languages (C#, Vb, C++, etc)
I've read Double checked locking pattern: Broken or not?, Is this broken double checked locking?, How to solve the "Double-Checked Locking is Broken" Declaration in Java? to be truthful i don't know what the common consensus is. some say yes its broken others say no.
Anyway, my question is does it also apply to other languages (C#, Vb, C++, etc)
This wikipedia article covers java, c++ and .net (c#/vb) http://en.wikipedia.org/wiki/Double-checked_locking
It was flawed in Java, it was fixed in Java 5. The fact that is was broken was more of an implementation issue coupled with a misunderstanding than a technically "bad idea".
This is a tricky question, with a mine-field of contradictory information out there.
A part of the problem is that there are a few variants of double-checked locking:
And not only that, different authors have a different definition for what it means that the pattern is "correct".
As disagreeable as it might seem, a lot of code out there depends on Definition #2.
Let's take C# as an example. In C#, the double-checked pattern (as typically implemented) is correct according to Definition #1 if and only if the field is volatile. But if we consider Definition #2, pretty much all variants are correct on X86 (i.e., happen to work), even if the field is non-volatile. On Itanium, the one-field variant happens to work if the field is non-volatile, but not the two-field variant.
The unfortunate consequence is that you'll find articles making clearly contradictory statements on the correctness of this pattern.
As others have said, this idiom has had its time. FWIW, for lazy initialization, .Net now provides a built-in class:
System.Lazy<T>
(msdn). Don't know if something similar is available in java though.Double checked locking is safe in Java, PROVIDED THAT:
volatile
, ANDMy source is the JSR-133 (Java Memory Model) FAQ - Jeremy Manson and Brian Goetz, February 2004. This is confirmed by Goetz in a number of other places.
However, as Goetz says, this is an idiom whose time has passed. Uncontended synchronization in Java is now fast, so he recommends that you just declare the
getInstance()
method assynchronized
if you need to do lazy initialization. (And I imagine that this applies to other languages too ...)Besides, all things being equal, it is a bad idea to write code that works in Java 5 but is unreliable in older JVMs.
OK, so what about the other languages? Well, it depends on how the idiom is implemented, and often on the platform.
C# - according to https://stackoverflow.com/a/1964832/139985, it is platform dependent whether the instance variable needs to be volatile. However, Wikipedia says that if you do use
volatile
or explicit memory barriers, the idiom can be implemented safely.VB - according to Wikipedia the idiom can be implemented safely using explicit memory barriers.
C++ - according to Wikipedia the idiom can be implemented safely using
volatile
in Visual C++ 2005. But other sources say that in general the C++ language specification doesn't provide sufficient guarantees forvolatile
to be sure. However double-checked locking can be implemented in the context of the C++ 2011 language revision - https://stackoverflow.com/a/6099828/139985.(Note: I'm just summarizing some sources I found which seem to me to be recent ... and sound. I'm not C++, C# or VB expert. Please read the linked pages and make your own judgements.)