安全从通用集合中获取Count值而不锁定集合?

时间:2009-08-29 21:01:38

标签: c# .net multithreading .net-3.5 locking

我有两个线程,一个将对象放入一个通用List集合的生产者线程和一个将这些对象从同一个通用List中拉出的消费者线程。我已经使用lock关键字正确地同步了对集合的读取和写入,并且一切正常。

我想知道的是,如果没有先锁定集合就可以访问Count属性。

JaredPar将Count属性in his blog称为可导致竞争条件的决策程序,如下所示:

if (list.Count > 0)
{
    return list[0];
}

如果列表中有一个项目,并且在访问Count属性之后但在索引器之前删除了该项目,则会发生异常。我知道了。

但是可以使用Count属性来确定初始大小是一个完全不同的集合吗? MSDN documentation表示实例成员不保证是线程安全的,所以我应该在访问Count属性之前锁定集合吗?

1 个答案:

答案 0 :(得分:18)

怀疑它的“安全”就“它不会导致任何灾难性的错误” - 但你可能会得到过时的数据。那是因为我怀疑它只是保存在一个简单的变量中,并且将来可能就是这种情况。但这与保证不一样。

就个人而言,我会保持简单:如果你正在访问共享的可变数据,那么只能在锁中使用(对同一数据使用相同的锁)。如果你有适当的隔离,那么无锁编程就是非常好的(所以你知道你有适当的内存障碍,并且你知道在你从它读取时你永远不会在一个线程中修改它在另一个)但听起来并非如此。

好消息是获得无争议的锁定非常便宜 - 所以如果我是你,我会选择安全的路线。在没有引入竞争条件的情况下,线程就足够了,这些竞争条件可能不会带来显着的性能优势,但会以罕见且不可重现的错误为代价。

相关问题