如果队列同步:
var _item = Queue.Synchronized(new Queue());
我可以在不使用锁定语句的情况下调用Enqueue和Dequeue等方法吗?
我目前的代码是:
lock (_item.SyncRoot)
{
_item.Enqueue(obj);
}
我可以线程安全使用:
_item.Enqueue(obj);
var item = _item.Dequeue();
答案 0 :(得分:4)
对Enqueue
的调用和Dequeue
的调用是线程安全的
但是,您的示例代码不是:
在调用Enqueue
和调用Dequeue
之间可能存在线程切换。这意味着,item
可能是obj
之外的另一个实例,或者对Dequeue
的调用会引发异常,因为它现在为空。
要使示例代码线程安全,您仍需要明确锁定:
lock(_item.SyncRoot)
{
_item.Enqueue(obj);
var item = _item.Dequeue);
}
只有现在才能保证,item
引用 - 在所有情况下都等于obj
。
答案 1 :(得分:4)
这几乎是SynchronizedQueue
的作用,但存在问题......通常您需要查看.Count
和 { {1}}在一个原子单元中 - 不检查.Dequeue()
(一个单位),然后检查.Count
(另一个单位) - 您完全不能信任.Dequeue()
一旦锁定被放弃,如果另一个线程偷走了工作,.Count
将抛出。
也许在4.0(.Dequeue()
)中尝试ConcurrentQueue<T>
,或使用.TryDequeue()
和Queue<T>
。
答案 2 :(得分:2)