是Queue.Count线程安全吗?

时间:2011-12-10 14:40:22

标签: c#

我需要一个线程来修改Queue(添加和删除元素),另一个线程只需要调用Queue.Count。它是安全的还是我需要使用locksConcurrentQueue

4 个答案:

答案 0 :(得分:3)

Queue不提供线程安全保证,所以是的,您确实需要提到的两种替代方案之一。

  

此类型的公共static(在Visual Basic中为Shared)成员是thread   安全。不保证任何实例成员都是线程安全的。

     

队列(Of T)可以同时支持多个读者,只要   集合未被修改。即便如此,通过集合进行枚举   本质上不是一个线程安全的过程。保证线程   枚举期间的安全性,您可以在期间锁定集合   整个枚举。允许多个访问集合   阅读和写作的线程,你必须实现自己的   同步。

答案 1 :(得分:3)

根据文档,Queue属性是线程安全的。

但它是一个原子int,可能发生的最糟糕的是你读错了(过时的)值。这可能是也可能不是问题。

但是,因为你必须做些什么来阻止你的阅读线程缓存你可能的值lock()

答案 2 :(得分:3)

不能保证线程安全。

Count的当前实现是线程安全的。它不太可能改变,但没有承诺。

大多数时候,这并不是非常有用。如果你正在做一些事情,比如输出当前估计的大小到UI,那么这是非常安全的。如果您在此基础上做出任何决定,那就不安全了:

if(queue.Count != 0)
  return queue.Dequeue; //not thread-safe as Dequeue isn't threadsafe.

if(queue.Count != 0)
{
  lock(queue)
    return queue.Dequeue; //not thread-safe, won't corrput
                          //queue but may error as Count could now be zero.
}
lock(queue)
  if(queue.Count != 0)
    return queue.Dequeue; //thread-safe

ConcurrentQueue<int> cQueue = new ConcurrentQueue<int>();
/*...*/
int val;
if(cQueue.TryDequeue(out val))
  return val; //perfectly thread-safe and lock-free,
              //but more expensive than single-threaded use of Queue<int>

答案 3 :(得分:0)

主题安全标题下的队列msdn documentation

  

此类型的公共static(在Visual Basic中为Shared)成员是thread   安全。 不保证所有实例成员都是线程安全的。

     

为了保证Queue的线程安全,所有操作必须是   通过Synchronized方法返回的包装器完成。

     

通过集合枚举本质上不是线程安全的   程序。即使集合是同步的,其他线程也可以   仍然修改集合,这会导致枚举器抛出一个   例外。为了在枚举期间保证线程安全,您可以   要么在整个枚举过程中锁定集合,要么抓住它   由其他线程所做的更改导致的异常。

msdn有很好的文档。我建议你下次去看那里。