C# 中的队列同步和操作
如果队列是同步的:
var _item = Queue.Synchronized(new Queue());
我可以在不使用lock语句的情况下调用Enqueue和Dequeue等方法吗?
我当前的代码是:
lock (_item.SyncRoot)
{
_item.Enqueue(obj);
}
我可以线程安全地使用:
_item.Enqueue(obj);
var item = _item.Dequeue();
If a Queue is syncronized:
var _item = Queue.Synchronized(new Queue());
can I call methods like Enqueue and Dequeue on it without using lock statements?
My current code is:
lock (_item.SyncRoot)
{
_item.Enqueue(obj);
}
Can I thread-safely use:
_item.Enqueue(obj);
var item = _item.Dequeue();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对
Enqueue
的调用和对Dequeue
的调用是线程安全的。但是,您的示例代码不是:
在对
Enqueue
的调用和对Dequeue
的调用之间可能存在线程切换。这意味着,item
可能是obj
之外的另一个实例,或者调用Dequeue
会引发异常,因为它现在是空的。为了使示例代码线程安全,您仍然需要显式锁定:
只有现在才能保证
item
引用在所有情况下都等于obj
。The call to
Enqueue
and the call toDequeue
are thread safe.However, your sample code is not:
Between the call to
Enqueue
and the call toDequeue
there could have been a thread switch. This means, thatitem
might be another instance thanobj
or the call toDequeue
throws an exception, because it now is empty.To make your sample code thread safe, you still need to lock explicitly:
Only now it is guaranteed, that
item
reference-equalsobj
in all circumstances.这几乎就是
SynchronizedQueue
所做的,但是有一个问题......通常您需要检查.Count
和< /strong>.Dequeue()
在一个原子单元中 - 不检查.Count
(一个单元)然后.Dequeue()
(另一个单元) ) - 你不能相信.Count
一旦锁被交出,完全,如果另一个线程窃取了工作,.Dequeue()
将抛出异常。也许在 4.0 中尝试
ConcurrentQueue
(使用.TryDequeue()
),或使用Queue
和lock
。That is pretty much what
SynchronizedQueue
does, but there is a problem... typically you need to check the.Count
and.Dequeue()
in one atomic unit - not check the.Count
(one unit) then.Dequeue()
(another unit) - you can't trust.Count
at all once the lock is surrendered, and.Dequeue()
will throw if another thread has stolen the work.Maybe try
ConcurrentQueue<T>
in 4.0 (with.TryDequeue()
), or useQueue<T>
andlock
.来自 MSDN
正如约翰·斯基特的回答所暗示的在这里,您可能更好或使用锁定,因为枚举可能会导致异常。
格雷格斯answer 还讨论了 Marc 提到的
Count
不是线程安全的问题。From MSDN
Just as John Skeet's answer suggests here, you might be better or using locking since enumerating might cause an exception.
Gregs answer also talks about what Marc mentions with the
Count
not being thread safe.