我需要一个线程来修改Queue(添加和删除元素),另一个线程只需要调用Queue.Count
。它是安全的还是我需要使用locks
或ConcurrentQueue
?
答案 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:
msdn有很好的文档。我建议你下次去看那里。此类型的公共static(在Visual Basic中为Shared)成员是thread 安全。 不保证所有实例成员都是线程安全的。
为了保证Queue的线程安全,所有操作必须是 通过Synchronized方法返回的包装器完成。
通过集合枚举本质上不是线程安全的 程序。即使集合是同步的,其他线程也可以 仍然修改集合,这会导致枚举器抛出一个 例外。为了在枚举期间保证线程安全,您可以 要么在整个枚举过程中锁定集合,要么抓住它 由其他线程所做的更改导致的异常。