C#的无锁哈希表

5
有没有人知道在C#中有无无锁哈希表的实现?或者有没有人可以确认HashTable上至少读取是线程安全的?
编辑:
我可以阅读文档,但不太清楚。
"当只有一个线程执行写入(更新)操作时,它是多线程使用的线程安全。"
所以问题是,如果我有多个线程,它们都可能写入哈希表,那么我将使用writerlock。然而,这些同样的线程也从哈希表中读取。读取时是否需要readerlock?

1
快速查看文档即可确认- http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx - RichardOD
6个回答

6

在集合被修改之前,读取操作是线程安全的。


3
文档中得知:
Hashtable可以被多个读线程和单个写线程安全使用。当只有一个线程执行写(更新)操作时,它也可用于多线程使用,这允许在Hashtable中无锁读取,前提是写入者被序列化到Hashtable中。要支持多个写入者,必须通过Synchronized方法返回的包装器执行Hashtable上的所有操作,前提是没有线程读取Hashtable对象。
遍历集合本质上不是线程安全的过程。即使集合已同步,其他线程仍然可以修改集合,这会导致枚举器抛出异常。为了保证枚举期间的线程安全性,您可以在整个枚举期间锁定集合或捕获由其他线程所做更改引起的异常。

3

谢谢,现在还很早,但这会让假期更有趣。 - Jon Hanna
@JonHanna 的链接已经失效了。你能更新一下吗?你还在继续开发它吗? - gkiko
@gkiko 我已经有一段时间没有处理它了,但自从我发布这个答案以来,它已经得到了改进(特别是,我编写 https://www.nuget.org/packages/SpookilySharp/ 的原因之一是它让我改进了一些常见的 .NET 哈希模式对于这种使用线性探测幂次表的负面性能影响)。 - Jon Hanna

2
此外,.NET 4.0 在 System.Collections.Concurrent 命名空间中添加了一个 ConcurrentDictionary。...

1

如果你不经常修改哈希表,那么你可以通过创建一个新的哈希表并在每次修改时交换它来编写自己的无锁哈希表 - 这样做效果很好(因为读取操作非常便宜,而写入操作非常昂贵)。

否则,我建议使用ReaderWriterLockSlim(假设你更多地进行读取操作)或Monitor(lock语句)(如果你经常进行写入操作)。


0

由于Orion的建议,您可能希望将哈希表与ReaderWriterLock结合使用。


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