【发布时间】:2015-08-17 09:22:32
【问题描述】:
在某些情况下,我真的很喜欢使用Guava's Striped 类。
C# 中是否有等价物?
【问题讨论】:
-
难道你不能通过拥有一组
n对象并将每个x锁定在arr[x.GetHashCode() % n]上来接近吗?
标签: c# concurrency guava
在某些情况下,我真的很喜欢使用Guava's Striped 类。
C# 中是否有等价物?
【问题讨论】:
n 对象并将每个x 锁定在arr[x.GetHashCode() % n] 上来接近吗?
标签: c# concurrency guava
看起来没有直接的等价物,但有一些无锁线程安全集合选项(我不确定你想要实现什么,所以我不能说它们是否适用你的场景)。看看System.Collections.Concurrent Namespace。
特别是,ConcurrentBag、ConcurrentQueue、ConcurrentStack 和 ConcurrentDictionary 都有不同的锁定/无锁线程安全策略。一些在this blog post中进行了解释。
您也许可以通过Partitioner 类获得您想要的,尽管我不确定具体的实现方式。
@Behrooz 说所有 .net 框架类型只对整个列表使用一个锁是不正确的。看看source for ConcurrentDictionary。第 71 行表明这个类是使用多个锁实现的。
如果你真的想,你可以写你自己的版本。 Guava Striped 的来源是:https://github.com/google/guava/blob/master/guava/src/com/google/common/util/concurrent/Striped.java
【讨论】:
我认为你能做的最好的事情就是实现你自己的,因为所有 dotnet 框架类型只为整个列表提供一个 lock。
为此,您可以使用 GetHashCode() 函数,模数(%)它与您想要的条纹数。并将其用作Tuple<TLock, List<T>>[] 的索引,其中 TLock 可以是在 System.Threading 命名空间中定义的任何类型的锁,而 T 是您要存储/访问的类型。
有了这个,您可以决定如何存储您的条纹。有诸如HashSet(在您的情况下效率低,因为您已经使用一些位来计算条带索引)、SortedSet、List、Array 之类的选择。
顺便说一句,谢谢你的问题,它会帮助我解决我遇到的问题。
【讨论】:
您是否尝试过来自 NuGet 的 Tamarind?
它是谷歌 Guava 库的 C# 端口
【讨论】:
我认为ConcurrentDictionary 可以存档类似的结果。
根据他们的文档:
所有这些操作都是原子的,并且对于 ConcurrentDictionary 类上的所有其他操作都是线程安全的。唯一的例外是接受委托的方法,即 AddOrUpdate 和 GetOrAdd。对于字典的修改和写入操作,ConcurrentDictionary 使用细粒度锁定来确保线程安全。 (对字典的读取操作以无锁方式执行。)但是,这些方法的委托在锁外调用,以避免在锁下执行未知代码可能出现的问题。因此,这些委托执行的代码不受操作的原子性影响。
如您所见,读操作是无锁的。例如,这将允许您在其他线程插入时不会阻止线程读取。
【讨论】: