Est-ce que le verrou (objlocker) élargit la portée de cet objet? Et les membres statiques sont-ils automatiquement thread-safe?

StackOverflow https://stackoverflow.com/questions/274344

Question

Lorsque vous verrouillez un objet, cet objet est-il verrouillé tout au long de l'application?

Par exemple, cet extrait de C # 3.0 en bref Section 19.6.1 "Types de threads sécurisés et .NET Framework":

static void AddItems(  )
  {
    for (int i = 0; i < 100; i++)
      lock (list)
        list.Add ("Item " + list.Count);

    string[] items;
    lock (list) items = list.ToArray(  );
    foreach (string s in items) Console.WriteLine (s);
  }

Est-ce que le premier verrou:

lock (list)
        list.Add ("Item " + list.Count);

empêcher un autre thread d'accéder à:

lock (list) items = list.ToArray(  );

ou les deux peuvent-ils être exécutés en même temps?

Et le CLR sécurise-t-il automatiquement le thread de vos méthodes statiques? Ou est-ce au développeur?

Merci, John

Était-ce utile?

La solution

class UsefulStuff {
    object _TheLock = new object { };
    public void UsefulThingNumberOne() {
        lock(_TheLock) {
            //CodeBlockA
        }
    }
    public void UsefulThingNumberTwo() {
        lock(_TheLock) {
            //CodeBlockB
        }
    }
}

CodeBlockA et CodeBlockB ne peuvent pas s'exécuter simultanément dans des threads différents, car ils sont tous deux verrouillés sur la même instance d'objet _TheLock .

Les méthodes sur _TheLock ne sont absolument pas affectées.

Autres conseils

Une autre chose à noter est que les constructeurs statiques SONT exécutés de manière sécurisée par le thread par le runtime. Si vous créez un singleton et le déclarez comme suit:

public class Foo
{
    private static Foo instance = new Foo();

    public static Foo Instance
    {
        get { return instance; }
    }
}

Ensuite, ce sera threadsafe. Si, toutefois, vous instanciez un nouveau Foo à l'intérieur du programme de lecture d'instance, vous devrez alors écrire votre propre sécurité de thread (verrouiller un objet, par exemple)

.

Le CLR ne rend pas automatiquement les méthodes statiques thread-safe; vous devez le faire vous-même.

lock (list) utilise cet objet comme verrou. Ainsi, si un thread différent atteint un autre point avec lock (list) (avec le même objet 'list'), l'autre thread bloquera jusqu'à ce que le premier thread relâche le verrou.

Pour être clair, lock (foo) ne "verrouille pas l'objet foo", mais acquiert le verrou associé à l'objet foo de sorte que la section critique (l'instruction dans la construction "lock (o) stmt" ;) ne s'exécute que lorsque le thread actuel a acquis le verrou.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top