2009-12-09 3 views
16

Eventuali duplicati:
Difference between lock(locker) and lock(variable_which_I_am_using)Perché i blocchi vengono eseguiti su oggetti separati?

In tutti gli esempi di codice "thread-safe" Ho visto, si bloccano su un oggetto fittizio separata. Perché i blocchi cant possono essere eseguiti direttamente sui dati in questione?

+0

ottima domanda, anche questo è stato il mio primo pensiero. – Russell

+1

Nell'interesse di aiutare le persone a trovare la risposta che stanno cercando, questa domanda non dovrebbe essere chiusa. @ Bill, la cosiddetta domanda duplicata esatta è impagabilmente intitolata e formulata e non indica chiaramente la domanda fondamentale a differenza di questa domanda. Credo che questa domanda sia molto più probabile per attirare l'attenzione nelle ricerche. Quindi ho votato per riaprire. – Ash

risposta

18

Il blocco su un oggetto dummy private separato garantisce che nessun altro si blocca su tale oggetto.

Se si bloccano i dati e lo stesso dato è visibile all'esterno, si perde tale garanzia. Ad esempio:

public class MyObject 
{ 
    public void SharedMethod() 
    { 
     lock (this) 
     { 
      // Do stuff 
     } 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     MyObject o = new MyObject(); 

     lock (o) 
     { 
      new Thread(() => 
      { 
       // Gets blocked 2s because of external lock 
       o.SharedMethod(); 
      }).Start(); 

      Thread.Sleep(2000); 
     } 
    } 
} 
+0

Bel esempio del problema. – RichardOD

+0

Penso di aver capito. Se si dispone di un oggetto fittizio separato, bloccando su un oggetto che si desidera utilizzare, non si impedisce che faccia qualcosa? – RCIX

+0

Voglio dire, quando provi a chiamare un metodo su quell'oggetto che ha bisogno di svegliare qualcosa. – RCIX

2

Ci sono alcune cose fantastiche su questo sul blog di Eric Gunnerson. Vedi here e here.

8

Jeff Richter (autore di CLR Via C#) spiega perché in questo articolo su Safe Thread Synchronization.

In particolare, in questo articolo la sezione "Perché la grande idea non è così grande" risponde alla tua domanda.

In realtà è un capitolo del libro CLR Via C#.

In conclusione, avere un oggetto privato come oggetto "synclock" consente alla classe di incapsulare e controllare qualsiasi blocco di cui la classe ha bisogno. Pertanto, indipendentemente dal numero di client che utilizzano la classe, il blocco viene eseguito in modo coerente e corretto.

+0

+1. Stavo per indicare il suo libro, ma questo articolo è effettivamente lo stesso! – RichardOD

+0

Se un oggetto deve essere bloccato durante determinate operazioni, e se il codice esterno può richiedere l'esecuzione di due o più operazioni senza il blocco tra di esse, l'oggetto deve esporre il blocco oi metodi per acquisirlo e rilasciarlo. L'esposizione di entrambi non consentirà semplicemente al codice esterno di eseguire correttamente ciò che deve fare. – supercat