在System.Collections.Concurrent.ConcurrentDictionary中防御竞争条件

goo*_*ate 4 c# multithreading .net-4.0 race-condition concurrentdictionary

.NET ConcurrentDictionary容易受到可能导致意外数据的竞争条件的影响,如本MSDN文章底部所述. 我假设有几个因素需要考虑.

问:我应该如何编写不易受可能导致数据丢失的竞争条件的代码?

在我的场景中,我有一个输入流,它具有一个始终增加的索引(n ++).我的想法是,如果竞争条件发生,我可以检测丢失的数据并重新发送.另一方面,可能有一种更好的方法可以做到这一点,我不知道.

Tud*_*dor 8

人们必须意识到并发集合(不限于.net)存在一个普遍的缺陷,即单个操作可能是线程安全的,但操作序列不是原子的.我的意思是:假设这个场景,我有一个带有a Check和一个Add操作的并发集合,都是原子的.

我想要做的是检查是否存在值,如果不存在,请添加它.所以我可以这样写:

if(!collection.Check(value)) 
{
    collection.Add(value);
}
Run Code Online (Sandbox Code Playgroud)

尽管两个操作都是原子操作,但上述顺序不是,因为线程可能在检查和另一个线程的添加之间中断,这导致不一致的结果.因此,整个序列应该通过将其包装在lock例如语句中而成为原子序列.

lock(locker)
{
   if(!collection.Check(value)) 
   {
       collection.Add(value);
   }
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为使用双重检查锁定更为理想.if(!collection.Check(value)){lock(locker){if(!collection.Check(value)){collection.Add(value); }}} (3认同)