以下C#類用於多線程環境。我刪除了很多實際的代碼。幾乎同時調用MethodA和MethodB時會出現問題。 IsDepleted屬性中的鎖定順序不能解決問題。從IsDepleted屬性中刪除鎖(WaitingQueue)解決了死鎖問題,但是當另一個線程從WaitingQueue.Count == 0和Processing.Count == 0語句之間的WaitingQueue中添加/刪除一個項時,此解決方案會導致問題。如何在下面的C#代碼中防止死鎖?
using System.Collections.Generic;
class Example
{
bool IsDepleted
{
get
{
lock (Processing)
{
lock (WaitingQueue)
{
return WaitingQueue.Count == 0
&& Processing.Count == 0;
}
}
}
}
private readonly List<object> Processing = new List<object>();
private readonly Queue<object> WaitingQueue = new Queue<object>();
public void MethodA(object item)
{
lock (WaitingQueue)
{
if (WaitingQueue.Count > 0)
{
if (StartItem(WaitingQueue.Peek()))
{
WaitingQueue.Dequeue();
}
}
}
}
public void MethodB(object identifier)
{
lock (Processing)
{
Processing.Remove(identifier);
if (!IsDepleted)
{
return;
}
}
//Do something...
}
bool StartItem(object item)
{
//Do something and return a value
}
}
在這種情況下,不需要有兩個鎖。 :) – 2009-01-14 19:00:51
如果你打算這樣做,那麼你總是雙引號鎖定,你可能會把它簡化爲一個鎖 – JoshBerke 2009-01-14 19:01:01
以相同的順序鎖定互斥鎖絕對是防止死鎖的必備工具。所需的鎖定順序並不意味着總是隻需要一個鎖。如果做得對,使用多個互斥體可以提高性能。 – gimpf 2009-01-14 19:48:06