.NET ConcurrentDictionary容易受到可能导致意外数据的竞争条件的影响at the bottom of this MSDN article.我假设有几个因素需要考虑。
问:我应该如何编写不易受可能导致数据丢失的竞争条件的代码?
在我的场景中,我有一个输入流,它总是增加索引(n ++)。我的想法是,如果竞争条件发生,我可以detect missing data并重新发送它。另一方面,有一种更好的方法可以做到这一点,我不知道。
答案 0 :(得分:6)
人们必须意识到并发集合(不限于.net)存在一个普遍的缺陷,即单个操作可能是线程安全的,但操作序列不是原子的。我的意思是:假设这个场景,我有一个Check
和Add
操作的并发集合,都是原子的。
我想要做的是检查是否存在值,如果不存在,请添加它。所以我可以这样写:
if(!collection.Check(value))
{
collection.Add(value);
}
尽管两个操作都是原子操作,但上述顺序不是,因为线程可能在检查和另一个线程的添加之间中断,这导致结果不一致。因此,整个序列应该通过将其包装在lock
语句中而成为原子序列。
lock(locker)
{
if(!collection.Check(value))
{
collection.Add(value);
}
}