2013-02-11 1 views
12

Data la seguente classe:Sono necessari più oggetti di blocco?

class x 
{ 
    Object lockOne = new Object(); 
    Object lockTwo = new Object(); 

    List<Something> listOne = new List<Something>(); 
    List<Something> listTwo = new List<Something>(); 

    void MethodOne() 
    { 
     lock(lockOne) 
     { 
      // some operation on listOne 
     } 
    } 

    void MethodTwo() 
    { 
     lock(lockTwo) 
     { 
      // some operation on listTwo 
     } 
    } 
} 

È corretto utilizzare due oggetti bloccaggio assumendo che MethodOne() e MethodTwo() può essere chiamato da diversi thread contemporaneamente rilevando che listOne e listTwo non sono correlati in alcun modo. Le uniche operazioni coinvolte nei blocchi sono quelle specificate nei commenti sopra.

+1

Si chiama splitting blocco ed è un buon modo per ridurre la contesa se i due oggetti e metodi sono indipendente. – assylias

+0

Dovrebbe essere definito di buon senso, farlo in senso contrario è una pessima pratica. – Dariusz

+0

Una delle cose che potresti voler vedere è usare un [ReaderWriterLock] (http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx). Se stai leggendo solo dall'elenco, consente a più thread di usarlo contemporaneamente ('List' ha letture thread-safe), una volta che hai bisogno di scrivere, aggiorna il lock e quindi solo un thread può scrivere e tutti i lettori sono bloccati, in seguito i lettori multipli possono ricominciare. –

risposta

7

Sì, è corretto. Evita di chiudere inutilmente un elenco solo perché l'altro elenco viene elaborato.

+2

corretto? Sì. Uno spreco? Inoltre sì, non sono necessari gli oggetti di blocco separati qui. – svick

+4

Per chiarire che cosa ha detto lo svick, non sta dicendo di bloccare un singolo oggetto di blocco ma [di non usare alcun oggetto di blocco a tutti] (http://stackoverflow.com/a/14814386/80274) e bloccare l'elenco stesso . –

6

Qui non sono necessari gli oggetti di blocco separati. Il seguente codice funziona altrettanto bene, con meno codice, meno spese e meno probabilità di errore utilizzare il blocco non corretta:

class x 
{ 
    List<Something> listOne = new List<Something>(); 
    List<Something> listTwo = new List<Something>(); 

    void MethodOne() 
    { 
     lock (listOne) 
     { 
      // some operation on listOne 
     } 
    } 

    void MethodTwo() 
    { 
     lock (listTwo) 
     { 
      // some operation on listTwo 
     } 
    } 
} 
+10

Come bestemmie, la best practice (come questa mostra) consiste nel bloccare solo gli elementi 'privati ​​'nella classe - altrimenti non sai quale codice esterno può tentare di bloccarlo quando e causa stallo o condizioni di gara . –