我正在尝试为常规 Queue 类实现线程安全的包装器。但似乎多个线程可能会获得相同的锁。所以我的问题是:
1. 怎么可能?
2、如何避免?
3.任何有用的建议都很高兴
这是我的队列:
public class SafeQueue<T> : SimpleQueue<T>
{
private readonly object sync = new object();
private readonly Queue<T> queue = new Queue<T>();
public override T Dequeue()
{
T item;
lock (sync)
{
Debug.Print("{1:mm ss ffff} {0} locked in dequeue", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
item = queue.Dequeue();
}
Debug.Print("{1:mm ss ffff} {0} unlocked dequeue", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
return item;
}
public override void Enqueue(T item)
{
lock (sync)
{
queue.Enqueue( item );
}
}
public override IEnumerator<T> GetEnumerator()
{
Queue<T> q;
lock (sync)
{
q = new Queue<T>(queue);
}
return ((IEnumerable<T>) q).GetEnumerator();
}
public override int Count
{
get
{
int c;
lock (sync)
{
Debug.Print("{1:mm ss ffff} {0} locked in count", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
c = queue.Count;
}
Debug.Print("{1:mm ss ffff} {0} unlocked count. Ret {2}", Thread.CurrentThread.ManagedThreadId, DateTime.Now,c);
return c;
}
}
}
这是我使用它的一块(工作是一个线程函数):
private readonly SafeQueue<string> taskQueue = new SafeQueue<string>();
private volatile bool stop = false;
...
private void Work()
{
while ( !stop )
{
string dir = null;
if (taskQueue.Count > 0)
{
dir = taskQueue.Dequeue();
}
...
所以,问题基本上是:两个线程获取 Count 属性的锁并返回一个正值。从那以后,他们都尝试使元素出队。