web-dev-qa-db-fra.com

Pourquoi l'objet de verrouillage doit-il être statique?

Il est très courant d'utiliser un objet statique privé readonly pour le verrouillage en mode multitâche. Je comprends que privé réduit les points d’entrée à l’objet de verrouillage en resserrant l’encapsulation et donc en donnant accès au plus essentiel.

Mais pourquoi statique?

private static readonly object Locker = new object();

À la fin, le champ n'est utilisé que dans ma classe, et je pourrais aussi simplement l'utiliser:

private readonly object Locker = new object();

Des commentaires?

PDATE:

A titre d'exemple, j'ai collé ce code (juste un exemple). Je pourrais utiliser un casier statique ou non statique à ce sujet et les deux fonctionneraient bien. Compte tenu de la réponse ci-dessous, je devrais plutôt définir mon casier comme ceci? (Désolé, j'ai une interview la semaine prochaine et j'ai besoin de connaître tous les détails :)

private readonly object Locker = new object();

Et voici le code:

    private int _priceA;
    private int _priceB;
    private EventWaitHandle[] _waithandle;
    private readonly IService _service;

//ctor
public ModuleAViewModel(IService service)
    {
        _service = service;
        _modelA = new ModelA();
        _waithandle = new ManualResetEvent[2];
        _waithandle[0] = new ManualResetEvent(false);
        _waithandle[1] = new ManualResetEvent(false);
        LoadDataByThread();
    }


 private void LoadDataByThread()
        {
            new Thread(() =>
                           {
                               new Thread(() =>
                               {
                                   lock (Locker)
                                   {
                                       _priceA = _service.GetPriceA();
                                   }
                                   _waithandle[0].Set();
                               }).Start();

                               new Thread(() =>
                               {
                                   lock (Locker)
                                   {
                                       _priceB = _service.GetPriceB();
                                   }
                                   _waithandle[1].Set();
                               }).Start();

                               WaitHandle.WaitAll(_waithandle);
                               PriceA = _priceA;
                               PriceB = _priceB;
                           }).Start();
        }

Merci

103
Houman

Il n'est pas "très courant d'utiliser un objet statique privé readonly pour le verrouillage en mode multithreading" - il est plutôt courant d'utiliser un verrou à la granularité appropriée/choisie. Parfois, c'est static. Le plus souvent, IMO, ce n'est pas - mais est basé sur instance .

L’heure principale où vous voyez un verrou static concerne un cache global ou un chargement différé de données/singletons globaux. Et dans ce dernier cas, il y a de meilleures façons de le faire de toute façon .

Cela dépend donc vraiment de la manière dont Locker est utilisé dans votre scénario. Protège-t-il quelque chose qui est lui-même statique? Si c'est le cas, le verrou devrait être statique. Si elle protège quelque chose qui est instance , alors le verrou IMO devrait également être basé sur une instance.

167
Marc Gravell

Il n'est pas nécessaire que ce soit statique, en fait parfois il devrait pas être statique.

La variable doit avoir la même portée que les méthodes où vous l'utilisez pour le verrouillage. Si les méthodes sont statiques, la variable doit être statique et si les méthodes sont des méthodes d'instance, la variable doit être une instance variable.

Une variable statique fonctionnera toujours si elle est utilisée pour verrouiller une méthode d'instance, mais vous allez alors trop verrouiller. Vous verrouillez toutes les méthodes dans toutes les instances, pas seulement les méthodes dans la même instance.

79
Guffa

L'étendue et la durée de vie d'un verrou peuvent/devraient dépendre de la "chose" que vous voulez verrouiller. Les verrous statiques sont principalement utilisés pour verrouiller des objets statiques.

27
Erno de Weerd