C# Queue.Count是线程安全的吗?
我需要一个线程来修改队列(添加和删除元素),另一个线程只调用C# Queue.Count是线程安全的吗?,c#,C#,我需要一个线程来修改队列(添加和删除元素),另一个线程只调用Queue.Count。它是安全的还是我需要使用锁或ConcurrentQueue?队列不提供线程安全保证,因此您确实需要您提到的两种选择之一 此类型的公共静态(在Visual Basic中共享)成员是线程 安全的。任何实例成员都不能保证线程安全 一个队列(T)可以同时支持多个读卡器,只要 集合未被修改。即使如此,通过集合枚举 本质上不是线程安全过程。保线 枚举期间的安全性,您可以在 整个枚举。允许多个用户访问集合的步骤 对于读写线程,
Queue.Count
。它是安全的还是我需要使用锁
或ConcurrentQueue
?队列
不提供线程安全保证,因此您确实需要您提到的两种选择之一
此类型的公共静态(在Visual Basic中共享)成员是线程
安全的。任何实例成员都不能保证线程安全
一个队列(T)可以同时支持多个读卡器,只要
集合未被修改。即使如此,通过集合枚举
本质上不是线程安全过程。保线
枚举期间的安全性,您可以在
整个枚举。允许多个用户访问集合的步骤
对于读写线程,您必须实现自己的线程
同步
从线程安全性标题下的队列:
此类型的公共静态(在Visual Basic中共享)成员是线程
安全的任何实例成员都不能保证线程安全。
为了保证队列的线程安全,所有操作都必须
通过同步方法返回的包装器完成
通过集合枚举本质上不是线程安全的
程序即使在同步集合时,其他线程也可以
仍然修改集合,这会导致枚举数抛出
例外。要保证枚举期间的线程安全,可以
在整个枚举过程中锁定集合或捕获
由其他线程所做的更改导致的异常
msdn有相当好的文档。我建议您下次再查看。根据文档,队列属性不是线程安全的
但是它是一个原子int,最糟糕的情况是你读取了错误的(过时的)值。这可能是个问题,也可能不是
但是,由于您必须采取措施防止读取线程缓存该值,因此您最好
lock()
它不能保证线程安全
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>
if(queue.Count!=0)
返回队列。退出队列//非线程安全,因为出列不是线程安全的。
如果(queue.Count!=0)
{
锁(队列)
return queue.Dequeue;//不是线程安全的,不会corrput
//队列,但可能会出错,因为计数现在可能为零。
}
锁(队列)
如果(queue.Count!=0)
返回队列。退出队列//线程安全
ConcurrentQueue cQueue=新ConcurrentQueue();
/*...*/
int-val;
if(cQueue.TryDequeue(out val))
返回val//完全线程安全且无锁,
//但是比队列的单线程使用更昂贵
我想我会更好地使用“extra int”。i、 e.在一个线程上,每次添加元素或从队列中删除元素时,我都会写入int count=queue.count
,从另一个线程中我会写入count
。顺便说一句,这是线程安全的吗?:)@javapowered:当然不安全,没有任何变化。您在count
上仍然有一个竞赛条件。但是会出现什么问题呢?我会收到某种例外情况吗?意外值?我看不出会有什么不同。现在你的“count”int不是线程安全的,除非你锁定它。@Joe我不从我访问的不同线程访问int
的Queue
方法。我也可以声明int
为volatile
读取过时的值对我来说很好,但是我可以读取错误的值吗?i、 e.int
的一半改变了,另一半没有改变。单词原子回答:不。但理论上,队列在排队或退队过程中可能会将其设置为某个奇怪的值,因此这仍然不是一个好主意。我只需要获得队列大小,就可以在UI中将其显示给用户,以供参考。我只是希望这不会在当前的实现中导致任何错误/异常,但是没有绝对的保证service pack或安全更新不会改变这一点。