Implementing the Multi-Threaded Singleton and the double-check locking mechanism. Is it ever really needed?

Implementing the Multi-Threaded Singleton…Can it be done without the double-check locking mechanism?

 

While sitting at my desk the other day, a developer came up and said we were implementing Singletons incorrectly…we need to be using the double-check locking mechanism. Of course my response was “No we don’t”. The CLR guarantees the order of static initialization and therefore negates the need to use that mechanism. Additionally, the framework guarantees thread safety with the initialization of static type variables. So ‘NO’ we don’t need to implement the double-locking mechanism.

 

Then the talk centered around. We need to do this when we want to perform lazy initialization. In other words, don’t initialize until we need it. Again, the answer is, we are implementing lazy initialization. The .Net framework will not initialize the variable until we call it for the first type. In other words, the following implementation works for the vast majority of implementations (excerpt taken from here on MSDN):

 

// .NET Singleton
sealed class Singleton 
{
    public static readonly Singleton Instance = new Singleton();
    private Singleton() {}
}

 

So I was shown the article on MSDN that caused the confusion, Implementing Singleton in C#. This article does not counter the previous article, it just presents other approaches. Specifically, it describes how to handle initialization of the Singleton within an Instance property in a multi-threaded environment. Specifically:

using System;
 
public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();
   private Singleton(){}
   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
         {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }
         return instance;
      }
   }
}

 

The article mentions it, but the real difference is that initialization is NOT being performed during static construction. This is a HUGE difference and if you need to do this, the method described in this article should be followed when initialization is occurring outside of construction. Given that, how often is this really needed?

 

Really, why not just do it in the private static constructor for the single instance that is created? For instance:

using System;
 
public sealed class Singleton
{
   private static readonly Singleton instance = new Singleton();
   private Singleton()
   {
      // Do additional stuff here. You even have access to the “this” variable
   }
   public static Singleton Instance
   {
      get{return instance;}
   }
}

I am not trying to shoot down the approach described in the article Implementing Singleton in C#. It is a valid and worthy approach for initialization outside of the constructor in a multi-threaded environment. However, if you perform initialization within the private constructor and leverage the CLR as just described, will you ever need to?

 

-Mathew Nolton

1 Comment

  • nice implementation scott. it looks like you used the singleton to wrap a form of the bridge pattern so you can vary the underlying implementation. i like it. i may have to borrow the idea later...



    -Mathew Nolton

Comments have been disabled for this content.