安全地得到泛型集合计数值没有锁定的集合?数值、安全

2023-09-03 04:57:19 作者:生锈的理想

我有两个线程,一个生产者线程对象放置到一个泛型列表集合和一个消费者线程,拉这些对象进行相同的通用清单。我有读取和写入使用lock关键字正确同步的集合,一切工作正常。

I have two threads, a producer thread that places objects into a generic List collection and a consumer thread that pulls those objects out of the same generic List. I've got the reads and writes to the collection properly synchronized using the lock keyword, and everything is working fine.

如果它是确定访问Count属性不先锁定集合什么我想知道的是。

What I want to know is if it is ok to access the Count property without first locking the collection.

JaredPar指Count属性in他的博客作为决策的过程,可导致竞争条件,像这样的:

JaredPar refers to the Count property in his blog as a decision procedure that can lead to race conditions, like this:

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

如果列表中有一个项目,并在访问Count属性之后,该项目被删除,但索引之前,会出现异常。我明白了。

If the list has one item and that item is removed after the Count property is accessed but before the indexer, an exception will occur. I get that.

然而这是确定使用Count属性,比方说,初步判断大小完全不同的集合?该 MSDN文档说,实例成员都不能保证是线程安全的,所以我应该锁访问计数属性之前收集?

But would it be ok to use the Count property to, say, determine the initial size a completely different collection? The MSDN documentation says that instance members are not guaranteed to be thread safe, so should I just lock the collection before accessing the Count property?

推荐答案

我的犯罪嫌疑人的是安全的它不会造成什么去了灾难性的错误的条件 - 但你可能获取陈旧数据。那是因为我的犯罪嫌疑人的它只是一个简单的变量中,而且这种很可能是在未来的情况。这是不一样的保证,但。

I suspect it's "safe" in terms of "it's not going to cause anything to go catastrophically wrong" - but that you may get stale data. That's because I suspect it's just held in a simple variable, and that that's likely to be the case in the future. That's not the same as a guarantee though.

我个人会保持简单:如果您在访问共享的可变数据,只有这样做锁定(使用相同的锁相同的数据)。无锁编程都非常好,如果你有适当的隔离到位(所以你知道你有合适的记忆障碍,你知道你将永远不会被修改它在一个线程中你从中读取,而在另一个),但它听起来好像不是这里的情况。

Personally I'd keep it simple: if you're accessing shared mutable data, only do so in a lock (using the same lock for the same data). Lock-free programming is all very well if you've got appropriate isolation in place (so you know you've got appropriate memory barriers, and you know that you'll never be modifying it in one thread while you're reading from it in another) but it sounds like that isn't the case here.

好消息是,收购一家无可争议的锁是令人难以置信的便宜 - 所以我去的安全路线,如果我是你。线程是够硬,而不会引入的比赛条件很可能会放弃任何显著的性能优势,但在罕见的unreproducible错误的成本。

The good news is that acquiring an uncontested lock is incredibly cheap - so I'd go for the safe route if I were you. Threading is hard enough without introducing race conditions which are likely to give no significant performance benefit but at the cost of rare and unreproducible bugs.