2009-01-07 110 views
13

我在讀關於線程和鎖定的內容。通常的做法是,你不能(不應該)鎖定一個值類型。如何正確鎖定值類型?

所以問題是,什麼是鎖定值類型的推薦方法?我知道有一些方法可以去做一件事,但我沒有看到一個例子。雖然MSDN論壇上有一個很好的主題,但我現在似乎無法找到。

謝謝

+2

你100%肯定,你需要修改的值類型的對象時,鎖定?當這樣一個裸體對象從一個線程傳遞到另一個線程時,會創建一個副本,這樣線程最終將處理2個不同的對象,這是安全的。 – 2009-01-07 16:52:59

回答

16

使用另一個對象進行鎖定。

int valueType; 
object valueTypeLock = new object(); 

void Foo() 
{ 
    lock (valueTypeLock) 
    { 
     valueType = 0; 
    } 
} 
+5

請記住使鎖對象只讀,或者可以將其更改爲不同的對象。在這種情況下,共享鎖假設可能會消失。 – 2010-05-15 03:36:43

+1

還要注意,這個特殊的例子是嚴格的學術。沒有合理的人會真的把`lock`放在`int`變量的簡單賦值上;該分配是原子性的,並且通過在字段聲明中使用`volatile`關鍵字,可以更高效且更輕鬆地實現寫入的最新可見性。 – 2016-08-23 21:00:59

1

取決於您的情況System.Threading.Interlocked在Jon的例子相同的代碼變成您可能能夠避免通過利用使用鎖:

System.Threading.Interlocked.Exchange(valueType,0) 
14

你的問題是這樣的措辭是它暗示我並不完全理解鎖定。您不鎖定數據,您鎖定以保護數據的完整性。你鎖定的對象是無關緊要的。重要的是,您鎖定代碼的其他區域中的同一對象,以改變受保護的數據。

+0

好的區別 – JoshBerke 2009-01-07 16:09:27

0

我一直在使用一個獨立的變量來鎖定:

object syncObj = new object(); 

void Foo() 
{ 
    lock(syncObj) 
    { 
    // do some stuff 
    } 
} 

鎖定在價值類型沒有任何意義,因爲值類型是不可改變的,不能修改。鎖定'this'也是有問題的,因爲'this'對外部世界是可見的。

有關監視器是如何原定的一些信息被用於看Monitor (synchronization)