Wenn du einen Werttyp gibst, wird er in eine Box gelegt, und beim nächsten Mal, wenn der Code hier ausgeführt wird, wird er erneut in eine Box gelegt, und es ist nicht zweimal dasselbe Objekt, sodass es nicht gesperrt werden kann
lock(x)
{ ...
}
Die Sperre erfolgt tatsächlich über das Monitor-Objekt:
Das oben Genannte entspricht bei:
System.Objekt obj = (System.Objekt)x; System.Threading.Monitor.Enter(obj); Versuch es
{ ...
} endlich
{ System.Threading.Monitor.Exit(obj);
}
Dann um die ursprünglichen Worte von MSDN zu zitieren: Verwenden Sie Monitor, um Objekte (also Referenztypen) zu sperren, nicht um Wertetypen. Wenn du eine Wert-Typ-Variable an Enter gibst, wird sie als Objekt geboxt. Wenn du dieselbe Variable erneut an Enter gibst, wird sie als separates Objekt geboxt, und der Thread blockiert nicht. In diesem Fall ist der Code, den Monitor angeblich schützen soll, nicht geschützt. Außerdem wird beim Weitergeben der Variablen an Exit noch ein weiteres separates Objekt erstellt. Da das an Exit übergebene Objekt sich von dem an Enter übergebenen Objekt unterscheidet, wirft Monitor SynchronizationLockException aus. Weitere Informationen finden Sie im konzeptionellen Thema Monitore. |