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 !