Singletons, double-checked locking in .NET and the others
I'm almost sure, most of my readers know, that the following code illustrating double-checking paradigm doesn't work in Java.
[JAVA] private static Object lockObject = new Object();
public static Filemon getInstance() { if (instance == null) { synchronized(lockObject) { if (instance == null) instance = new Filemon(); } } return instance; [/JAVA]
The reason is a java memory model and further description can be read f.e. here or here
Inspired by threading puzzles published by Rene and Dagi, I was thinking about the situation in .NET. Is this paradigm broken there as well?
And the answer for the question after reading several articles and blogs is: YES. The reason again is the memory model being used in CLR.
The proposed solution is either to use volatile modifier for the singleton instance eg.
[java] public class Filemon {
private static volatile Filemon instance; private static object lockObject = new Object();
public static Filemon Instance { get { if (Filemon.instance == null) { lock (lockObject) { if (Filemon.instance == null) { Filemon.instance = new Filemon(); } } } return Filemon.instance; } } } [/java]
To avoid performance bottleneck caused by the usage of a volatile variable somebody suggests to issue the explicit memory barrier to wait for a complete initialization of object and to flush the caches and thus propagate the changes to the memory visible to all concurrent threads like this:
[java] public class Filemon {
private static Filemon instance; private static object lockObject = new Object();
public static Filemon Instance { get { if (Filemon.instance == null) { lock (lockObject) { if (Filemon.instance == null) { Filemon newInstance = new Filemon(); System.Threading.Thread.MemoryBarrier(); Filemon.instance = newInstance; } }
}
return Filemon.instance; } } } [/java]
Another working singleton solution is based upon a static initializer
[java] public class FilemonStatic { static readonly FilemonStatic instance=new FilemonStatic();
static FilemonStatic() {}
public static FilemonStatic GetInstance() { return instance; } } [/java]
In this case we apparently loosing the laziness present in the above snippets. To avoid this, a special type attribute beforeFieldInit could be used. This attribute should cause the initialization of the class to happen during its very first access. However the attribute seems to be a little bit mysterious - see the following article.
I'm too lazy today to do any performance tests of the solutions published in this post. :)

