I’m almost sure, most of my readers know, that the following code illustrating double-checking paradigm doesn’t work in Java.
private static Object lockObject = new Object(); public static Filemon getInstance() { if (instance == null) { synchronized(lockObject) { if (instance == null) instance = new Filemon(); } } return instance;
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.
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; } } }
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:
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; } } }
Another working singleton solution is based upon a static initializer
public class FilemonStatic { static readonly FilemonStatic instance=new FilemonStatic(); static FilemonStatic() {} public static FilemonStatic GetInstance() { return instance; } }
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. 🙂
Pingback: online poker
Cialis http://www.cheap-drug-online.com/cialis.php buy order cialis (tadalafil).
Thats a very good idea, even one of the best !