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.

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. 🙂

3 thoughts on “Singletons, double-checked locking in .NET and the others

  1. Pingback: online poker

Comments are closed.