線程在以下場景中等待競態條件需要多長時間?鎖將如何響應競爭條件?
的文件被添加到集合:
lock(mylock)
{
// add to collection
}
它是從集合中一個類似的方式然後取出。
如果某個線程試圖在服務將其從集合中刪除時嘗試添加到集合中,誰會贏?
或者說是一個競爭條件的點,你無法預測誰贏了?
線程在以下場景中等待競態條件需要多長時間?鎖將如何響應競爭條件?
的文件被添加到集合:
lock(mylock)
{
// add to collection
}
它是從集合中一個類似的方式然後取出。
如果某個線程試圖在服務將其從集合中刪除時嘗試添加到集合中,誰會贏?
或者說是一個競爭條件的點,你無法預測誰贏了?
如果刪除線程試圖首先鎖定,它擁有鎖定,刪除項目(如果存在),釋放鎖定,然後繼續。然後添加線程抓住鎖並添加項目。 最終結果:項目存在於集合中。
如果添加線程先嚐試鎖定,則它擁有鎖定,添加項目,釋放鎖定,然後繼續。然後刪除線程抓住鎖並刪除(剛添加的)項。 最終結果:項目不存在存在於集合中。
這兩個線程都不會等待比添加或刪除集合中的項目所需時間更長的時間。
無論哪個線程首先發出鎖都會贏。第二個線程將一直等到第一個線程釋放鎖定。
顧名思義,競賽條件意味着有一場比賽,任何人都可以獲勝!
使用lock(obj)
就像您在這裏顯示的那樣會導致線程阻塞(等待),直到所有其他線程在obj
上釋放它們的鎖定。這可能永遠不會發生。
lock (obj)
{
// stuff
}
...等價於...
Monitor.Enter(obj);
try
{
// stuff
}
finally
{
Monitor.Exit(obj);
}
如果要強制執行鎖定超時,改用此表單:
if (!Monitor.TryEnter(obj, timeout))
{
// handle the fact that you couldn't lock
}
else
{
try
{
// stuff
}
finally
{
Monitor.Exit(obj);
}
}
有一種別樣'if'和'try'之間的競爭條件。例如,如果線程在兩者之間中止,則它將離開代碼鎖定的部分。我不認爲這是你問題的關鍵,但那裏仍然存在問題。
我喜歡你的答案,我現在可以想象這個問題,謝謝。 – Blankman 2009-02-18 20:56:59