specifica ECMA-335 indica:interblocco Monitor.Enter e Monitor.Exit blocchi
* acquisizione di un blocco (System.Threading.Monitor.Enter o immettendo un metodo sincronizzato) svolgeranno implicitamente una lettura volatili operazione, e rilasciando un blocco (System.Threading.Monitor.Exit o lasciando un metodo sincronizzato) eseguirà implicitamente un'operazione di scrittura volatile. (...)
Una lettura volatili ha acquisire semantica significa che la lettura viene garantito avvengano prima tutti i riferimenti a memoria che si verificano dopo l'istruzione di lettura della sequenza di istruzioni CIL. Una scrittura volatile ha una semantica di rilascio che significa che la scrittura è garantita per accadere dopo qualsiasi riferimento di memoria prima dell'istruzione di scrittura nella sequenza di istruzioni CIL. *
Ciò significa che i compilatori non possono spostare istruzioni fuori da Monitor.Enter/Monitor.Esci i blocchi, ma non è vietato spostare altre istruzioni nel blocco. Forse, anche un altro Monitor.Enter potrebbe essere spostato nel blocco (come può essere scambiato una scrittura volatile seguita da una lettura volatile). Quindi, potrebbe il seguente codice:
class SomeClass
{
object _locker1 = new object();
object _locker2 = new object();
public void A()
{
Monitor.Enter(_locker1);
//Do something
Monitor.Exit(_locker1);
Monitor.Enter(_locker2);
//Do something
Monitor.Exit(_locker2);
}
public void B()
{
Monitor.Enter(_locker2);
//Do something
Monitor.Exit(_locker2);
Monitor.Enter(_locker1);
//Do something
Monitor.Exit(_locker1);
}
}
, essere trasformato in un equivalente del followig:
class SomeClass
{
object _locker1 = new object();
object _locker2 = new object();
public void A()
{
Monitor.Enter(_locker1);
//Do something
Monitor.Enter(_locker2);
Monitor.Exit(_locker1);
//Do something
Monitor.Exit(_locker2);
}
public void B()
{
Monitor.Enter(_locker2);
//Do something
Monitor.Enter(_locker1);
Monitor.Exit(_locker2);
//Do something
Monitor.Exit(_locker1);
}
}
, che possano portare a situazioni di stallo? O mi sto perdendo qualcosa?
Stai parlando di due cose molto diverse. Ciò che è rilevante è che né il compilatore né il jitter potranno mai riordinare le chiamate di metodo. –
Hmm ... domanda interessante. Non sono sicuro di essere pronto a comprare il metodo di riordino del problema, eppure ancora. Intendo cosa succederebbe se l'ottimizzazione dell'innesto avvenga * prima * dell'ottimizzazione del sollevamento. C'è una clausola nelle specifiche che impedirebbe questo? –