如果我们有一个ConcurrentBag<object>
safeBag`填充了100个对象。
然后一个线程起作用:
foreach(object o in safeBag)
{
Thread.Sleep(1000);
}
另一个线程在第一个线程启动后立即启动:
{
safeBag.AddOrTake(something);
}
第二个线程是否会等待100Sec进入资源? 另一个问题,如果第一个线程运行Parallel.ForEach(),线程将如何工作?
编辑:MSDN说:“只要集合没有被修改,List就可以同时支持多个读者。通过集合枚举本质上不是一个线程安全的过程。在极少数情况下枚举与一个或更多写访问,确保线程安全的唯一方法是在整个枚举期间锁定集合。“通过ConcurrentBag枚举是否会导致第二个线程在写入ConcurrentBag时等待写入?答案 0 :(得分:2)
对于大多数Concurrent*
个集合,大多数操作都是原子操作,但不会持有任何长期锁定。在GetEnumerator()
返回后,第一个线程不会阻塞第二个线程。
ConcurrentBag<T>.GetEnumerator
Method
枚举表示行李内容的即时快照。调用GetEnumerator后,它不会反映对集合的任何更新。该枚举器可以安全地与读取和写入包同时使用。
答案 1 :(得分:0)
第二个线程,假设你正在连续产生两个线程 - 第一个使用ThreadStart
指向包含迭代的块,第二个指向另一个代码块,不会等待1000ms 。 foreach
块在移动到集合中的下一个对象之间只需等待1秒,第二个块不受此影响。
如果它是一个并行的foreach,那么在移动到下一个元素之前,你会有几个线程等待一秒(同时)。第二个区块仍然没有等待ConcurrentBag
获得免费。