.NET ConcurrentDictionary 容易受到可能导致意外数据的竞争条件的影响,如本 MSDN 文章底部所述。 我假设有几个因素需要考虑。
问:我应该如何编写不易受到可能导致数据丢失的竞争条件的代码?
在我的场景中,我有一个输入流,它的索引总是增加(n++)。我的想法是,如果出现竞争条件并重新发送它,我可以检测到丢失的数据。另一方面,我不知道可能有更好的方法来做到这一点。
.NET ConcurrentDictionary 容易受到可能导致意外数据的竞争条件的影响,如本 MSDN 文章底部所述。 我假设有几个因素需要考虑。
问:我应该如何编写不易受到可能导致数据丢失的竞争条件的代码?
在我的场景中,我有一个输入流,它的索引总是增加(n++)。我的想法是,如果出现竞争条件并重新发送它,我可以检测到丢失的数据。另一方面,我不知道可能有更好的方法来做到这一点。
人们必须意识到并发集合(不限于 .net)的一个普遍缺陷,即单个操作可能是线程安全的,但操作序列不是原子的。我的意思如下:假设在这种情况下,我有一个带有 aCheck
和一个Add
操作的并发集合,两者都是原子的。
我想要做的是检查一个值是否存在,如果不存在,添加它。所以我可以这样写:
if(!collection.Check(value))
{
collection.Add(value);
}
虽然这两个操作都是原子的,但上述顺序不是,因为一个线程可能会在检查和添加之间被另一个线程中断,从而导致结果不一致。因此,整个序列应该是原子的,例如将其包装在一个lock
语句中。
lock(locker)
{
if(!collection.Check(value))
{
collection.Add(value);
}
}