2008-11-08 9 views
1

Lorsque vous verrouillez un objet, cet objet est-il verrouillé dans toute l'application?Est-ce que le verrou (objlocker) permet de sécuriser l'application thread thread? Et les membres statiques sont-ils automatiquement sécurisés?

Par exemple, cet extrait de C# 3.0 dans un Nutshell Section 19.6.1 "Enfilez Types de sécurité 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 une autre thread d'accès:

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

ou peuvent être exécutés en même temps?

Et le CLR rend-il automatiquement vos threads de méthodes statiques sûrs? Ou est-ce à la hauteur du développeur?

Merci, John

Répondre

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

CodeBlockA et CodeBlockB sont empêchés d'exécuter en même temps dans les différents threads, car ils sont tous deux verrouillés sur la même instance d'objet _TheLock.

Les méthodes sur _TheLock lui-même ne sont pas affectées.

+0

Merci de l'avoir éclairci pour moi. – John

3

Le CLR ne thread-safe pas automatiquement les méthodes statiques; vous devez le faire vous-même. Lock (list) utilise cet objet comme verrou, donc 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 plutôt 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 en cours a acquis le verrou.

+0

Merci pour votre réponse rapide! – John

5

Une autre chose à noter est que les constructeurs statiques sont exécutés de manière thread-safe par le moteur d'exécution. Si vous créez un singleton et le déclarez comme:

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

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

Ensuite, il sera threadsafe. Cependant, si vous instanciez un nouveau Foo à l'intérieur du getter Instance, vous devrez alors écrire votre propre sécurité de thread (c'est-à-dire verrouiller un objet)

Questions connexes