99 votes

Modèle de singleton C# sans threads

J'ai quelques questions concernant le modèle singleton tel que documenté ici : http://msdn.microsoft.com/en-us/library/ff650316.aspx

Le code suivant est un extrait de l'article :

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;
      }
   }
}

Plus précisément, dans l'exemple ci-dessus, est-il nécessaire de comparer l'instance à null deux fois, avant et après le verrouillage ? Est-ce nécessaire ? Pourquoi ne pas effectuer le verrouillage d'abord et faire la comparaison ensuite ?

Y a-t-il un problème à simplifier à ce qui suit ?

   public static Singleton Instance
   {
      get 
      {
        lock (syncRoot) 
        {
           if (instance == null) 
              instance = new Singleton();
        }

         return instance;
      }
   }

L'exécution de la serrure est-elle coûteuse ?

3voto

Dennis Traub Points 24186

Jetez un coup d'œil à Le modèle Singleton de Jon Skeet en C# . Dans cet article, il explique très bien comment cela fonctionne et pourquoi il y a une seconde null -Vérifier.

3voto

Jeffrey Richter recommande de suivre :

    public sealed class Singleton
    {
        private static readonly Object s_lock = new Object();
        private static Singleton instance = null;

        private Singleton()
        {
        }

        public static Singleton Instance
        {
            get
            {
                if(instance != null) return instance;
                Monitor.Enter(s_lock);
                Singleton temp = new Singleton();
                Interlocked.Exchange(ref instance, temp);
                Monitor.Exit(s_lock);
                return instance;
            }
        }
    }

2voto

Pranaya Rout Points 141

C'est ce qu'on appelle le mécanisme de verrouillage à double vérification. Tout d'abord, nous allons vérifier si l'instance est créée ou non. Si ce n'est pas le cas, alors seulement nous synchroniserons la méthode et créerons l'instance. Cela améliorera considérablement les performances de l'application. Effectuer un verrouillage est lourd. Donc, pour éviter le verrouillage, nous devons d'abord vérifier la valeur nulle. Ceci est également thread safe et c'est la meilleure façon d'obtenir les meilleures performances. Veuillez regarder le code suivant.

public sealed class Singleton
{
    private static readonly object Instancelock = new object();
    private Singleton()
    {
    }
    private static Singleton instance = null;

    public static Singleton GetInstance
    {
        get
        {
            if (instance == null)
            {
                lock (Instancelock)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
}

1voto

Brian Ogden Points 1954

Vous pouvez créer rapidement une instance Singleton à sécurité thread, selon les besoins de votre application, c'est un code succinct, bien que je préfère la version paresseuse de @andasa.

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();

    private Singleton() { }

    public static Singleton Instance()
    {
        return instance;
    }
}

0voto

Jaydeep Shil Points 898

Une autre version de Singleton où la ligne de code suivante crée l'instance Singleton au moment du démarrage de l'application.

private static readonly Singleton singleInstance = new Singleton();

Ici, le CLR (Common Language Runtime) se charge de l'initialisation des objets et de la sécurité des threads. Cela signifie que nous n'aurons pas besoin d'écrire de code explicite pour gérer la sécurité des threads dans un environnement multithread.

"Le chargement Eager dans le modèle de conception singleton n'est rien d'un processus en dans lequel nous devons initialiser l'objet singleton au moment du démarrage de l'application plutôt que sur demande et le garder prêt en mémoire pour être utilisé dans le futur".

public sealed class Singleton
    {
        private static int counter = 0;
        private Singleton()
        {
            counter++;
            Console.WriteLine("Counter Value " + counter.ToString());
        }
        private static readonly Singleton singleInstance = new Singleton(); 

        public static Singleton GetInstance
        {
            get
            {
                return singleInstance;
            }
        }
        public void PrintDetails(string message)
        {
            Console.WriteLine(message);
        }
    }

du principal :

static void Main(string[] args)
        {
            Parallel.Invoke(
                () => PrintTeacherDetails(),
                () => PrintStudentdetails()
                );
            Console.ReadLine();
        }
        private static void PrintTeacherDetails()
        {
            Singleton fromTeacher = Singleton.GetInstance;
            fromTeacher.PrintDetails("From Teacher");
        }
        private static void PrintStudentdetails()
        {
            Singleton fromStudent = Singleton.GetInstance;
            fromStudent.PrintDetails("From Student");
        }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X