我正在看這個msdn關於與Monitor.Pulse()的線程同步的頁面上的示例2。生產者 - 消費者示例,都在鎖(此)塊
Cell對象被創建並傳遞給生產者和消費者對象。
Cell cell = new Cell();
CellProd prod = new CellProd(cell, 20);
CellCons cons = new CellCons(cell, 20);
一個線程的每一個這兩個
Thread producer = new Thread(new ThreadStart(prod.ThreadRun));
Thread consumer = new Thread(new ThreadStart(cons.ThreadRun));
創建的ThreadRun在每種情況下一個循環,調用Cell.ReadFromCell()或Cell.WriteToCell(),取決於消費者/生產者。例如,製作者這
public void ThreadRun()
{
for(int looper=1; looper<=quantity; looper++)
cell.WriteToCell(looper); // "producing"
}
我不明白的一點是,在每一種方法,他們開始用
lock(this)
而且由於它是一樣的Cell對象(即,上面的鎖定語句中的'this')傳遞給兩者,我一直以爲只有一個線程可以在這段代碼中。然而,從Monitor.Pulse()和Monitor.Wait()後面的代碼看來,這兩個線程同時在這些部分中。如果有人擁有該鎖,並且擊中了一個Monitor.Wait(),那麼另一個線程就永遠不會Pulse,因爲它被阻塞等待鎖定。
我猜測有一個簡單的解決方案,我誤解了一些東西,從我的測試運行代碼它看起來像兩個線程同時在他們的關鍵部分,所以鎖(這)不是做我應該做的印象。
請注意,這是一種糟糕的編程習慣來「鎖定(this)」。相反,創建一個類型爲object的私有字段並對其進行鎖定。這是一個不好的做法,因爲*任何人*都可以鎖定該對象;如果您的鎖定訂單保證僅取決於*內部的代碼*可以鎖定的類型然後鎖定這會使代碼變得脆弱而難以分析。鎖定私鑰意味着你知道*只有*可以獲得對私鑰對象的引用的代碼才能取出鎖。 –
Eric,我完全同意,但MSDN不應該首先提供這樣的示例代碼。大多數時候,人們使用'lock(this)'語句是因爲他們認爲如果它在MSDN上,它必須是正確的方法。有沒有辦法提交更新MSDN內容的請求? – SolutionYogi
@SolutionYogi:好點。我會將其提請文檔管理員注意。謝謝! –