C# Language Singleton paresseux et thread-safe (à l'aide du verrouillage à double contrôle)


Exemple

Cette version thread-safe d'un singleton était nécessaire dans les premières versions de .NET où static initialisation static n'était pas garantie pour être thread-safe. Dans les versions plus modernes du framework, un singleton statiquement initialisé est généralement préféré car il est très facile de faire des erreurs d'implémentation dans le modèle suivant.

public sealed class ThreadSafeSingleton
{
   private static volatile ThreadSafeSingleton instance;
   private static object lockObject = new Object();

   private ThreadSafeSingleton()
   {
   }

   public static ThreadSafeSingleton Instance
   {
      get 
      {
         if (instance == null) 
         {
            lock (lockObject) 
            {
               if (instance == null)
               {
                  instance = new ThreadSafeSingleton();
               }
            }
         }

         return instance;
      }
   }
}

Notez que la vérification if (instance == null) est effectuée deux fois: une fois avant l’acquisition du verrou et une fois par la suite. Cette implémentation serait toujours thread-safe même sans la première vérification NULL. Cependant, cela signifierait qu'un verrou serait acquis à chaque fois que l'instance est demandée, ce qui pourrait nuire à la performance. La première vérification NULL est ajoutée afin que le verrou ne soit pas acquis, sauf si nécessaire. La deuxième vérification NULL garantit que seul le premier thread à acquérir le verrou crée alors l'instance. Les autres threads trouveront l'instance à remplir et passeront à la suite.