为什么要使用Hashtable.Synchronized?

4

来自MSDN文档:

“如果没有线程正在读取Hashtable,则同步支持多个写入线程。 在存在一个或多个读取器和一个或多个写入器的情况下,同步包装器不提供线程安全访问。”

Source: http://msdn.microsoft.com/en-us/library/system.collections.hashtable.synchronized.aspx

听起来我仍然需要使用锁,那么我的问题是为什么我们还要使用Hashtable.Synchronized呢?


在 .NET 3.5 及更高版本(我知道这是一个老问题),支持多个读者和写者是安全的。 - mhenry1384
3个回答

3
出于同样的原因,数据库事务存在不同的级别。您可能关心写入操作是否得到保证,但不介意读取过时/可能有问题的数据。
编辑 我注意到他们的具体示例是一个枚举器。他们无法在其包装器中处理此情况,因为如果您提前从枚举中退出,则包装器类将无法知道它可以释放其锁定。

相反,考虑计数器的情况。多个线程可以增加表中的值,并且您想要显示计数的值。将1,200,453显示出来并且实际计数是1,200,454也没关系,只需接近即可。但是,您不希望数据损坏。这是写入时需要线程安全性但读取时不需要的情况。

当你说“你不想数据被损坏”时,如果数据被损坏,那会是什么样子?我认为显示错误的计数就是数据损坏。 - makstaks
1
如果Google说有1,200,453个页面,因为刚刚添加了第1,200,454个页面,并且在请求时更新计数的Hashtable条目,我不认为这是一个问题。 GAE中分片计数器的整个概念都基于这个原则。 - Chris Marasti-Georg

1

对于这种情况,您可以保证在写入数据结构时没有读取器会访问它(或者当您不关心读取错误的数据时)。例如,当结构不断被修改而是一次性计算,您稍后将需要访问它,尽管足够大以保证许多线程写入它。


所有多线程写入这个同步数据结构的最终结果,是否与我在数据结构上加锁时得到的最终结果相同? - makstaks

0

当你在一个线程上使用for-each循环遍历哈希表(读取)时,如果存在其他可能添加/删除项目的线程(写入),则需要它...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接