Il blocco (objlocker) rende l'app thread thread sicuro su larga scala? E i membri statici sono automaticamente thread-safe?

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

Domanda

Quando si blocca un oggetto, quell'oggetto è bloccato nell'intera applicazione?

Ad esempio, questo frammento di C # 3.0 in una sezione Nutshell 19.6.1 "Tipi di sicurezza thread e .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);
  }

Fa il primo blocco:

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

impedisce ad un altro thread di accedere:

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

o possono essere eseguiti entrambi contemporaneamente?

E il CLR rende automaticamente sicuro il tuo thread dei metodi statici? Oppure dipende dallo sviluppatore?

Grazie, John

È stato utile?

Soluzione

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

CodeBlockA e CodeBlockB non possono essere eseguiti contemporaneamente in thread diversi, poiché entrambi sono bloccati sulla stessa istanza dell'oggetto _TheLock .

I metodi su _TheLock sono completamente inalterati.

Altri suggerimenti

Un'altra cosa da notare è che i costruttori statici vengono eseguiti in modo sicuro dal runtime. Se stai creando un singleton e dichiaralo come:

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

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

Quindi sarà sicuro per i thread. Se tuttavia, crei un'istanza di un nuovo Foo all'interno del getter dell'istanza, dovrai scrivere la sicurezza del tuo thread (es. Bloccare un oggetto)

Il CLR non rende automaticamente i metodi statici thread-safe; devi farlo da solo.

lock (list) usa quell'oggetto come lock, quindi se un thread diverso raggiunge un altro punto con lock (list) (con lo stesso oggetto 'list'), l'altro thread si bloccherà fino a quando il primo thread non rilascia il lock.

Per essere chiari, lock (foo) non "blocca l'oggetto foo", ma acquisisce il blocco associato all'oggetto foo in modo che la sezione critica (l'istruzione nel costrutto "lock (o) stmt "" ;) viene eseguito solo quando il thread corrente ha acquisito il blocco.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top