2009-10-07 25 views
4

我不確定鎖是如何工作的。
如果我有List<T> list和2個線程會發生什麼?
這在線程開始第一跑步和枚舉列表如果我鎖定一個對象而另一個線程使用該變量會發生什麼?

foreach(T t in list) 
{ 
    // code 
} 

,並在同一時間,但線程1開始後,線程2將鎖定列表

lock(list) 
{ 
    // code 
} 

我用ThreadPool做一些會發生什麼處理和我需要知道如何鎖真正的工作,如果線程安全

ThreadPool.QueueUserWorkItem(new WaitCallback(method), obj); 

回答

5

lock keyword d不會「鎖定」或「凍結」目標對象(從某種意義上來說可防止更改)。

鎖確保一個線程不會進入代碼的關鍵部分,而另一個線程處於關鍵部分。如果另一個線程試圖輸入一個鎖定的代碼,它將等待,阻止,直到該對象被釋放。

所以在你的情況下,它不會阻止其他線程枚舉列表。

5

在編寫的代碼中 - 枚舉器將繼續前進。關於lock的一點是,全部您的代碼需要同意。如果您用過:

lock(list) 
{ 
    foreach(T t in list) 
    { 
     // code 
    } 
} 

那麼當你其他線程試圖獲取鎖,將隊列中的第一背後 - 等待第一個線程釋放鎖(無論是通過退出lockMonitor.Exit)或致電Monitor.Wait)。

+0

當我有兩種方法時,情況如何呢? AddValue和GetValue?我在兩種方法中都使用lock(someObj){}。但是我聽說過當一個線程在另一個線程調用GetValue的同時調用AddValue時的情況 - 集合將被修改並拋出異常。同步對象是否保證在其lock()構造中使用它的所有方法也將被阻止?換句話說,我需要在閱讀時屏蔽所有的寫操作......這對我來說並不明確...... – Laserson 2011-09-02 15:54:04

+1

@Laserson是使用來自***所有***來電者的鎖將停止這是一個問題。在大多數情況下,排他性的短暫時期不是問題,但是如果讀取線程多於寫入線程,請查看ReaderWriterLockSlim,它允許一個寫入程序** NAND **多個讀取程序 – 2011-09-02 16:08:33

1

鎖定不是魔術,它必須協作使用。如果我想確保對某些可變對象的更改不會被意外踩踏或被多個線程損壞,那麼我需要確保只對鎖塊內的對象進行更改。

鎖確保唯一的事情是鎖定在同一對象上的任何其他代碼不會同時在其他線程上運行,它只是用於獲取和釋放互斥鎖的語法糖。

lock(x) // acquire mutex associated with x, or wait until it becomes available 
{ 
    // do stuff 
} // release mutex associated with x 

編輯:MSDN非常值得under-the-hood details on lock(),對於那些很好奇。

+0

雖然它是*邏輯*互斥量,注意這個('Monitor')與操作系統提供的互斥體非常不同,在.NET中公開爲'Mutex'。 – 2009-10-07 11:46:01

+0

@Marc,是的,這是真的,在引擎蓋下lock()使用了一個Monitor,它使用了一個(little-m)互斥體,但是這不應該與通常用於(大m)互斥體的mutex類混淆跨進程同步。 – Wedge 2009-10-07 12:10:34

相關問題