在C#中是否有与Guava Striped-Class相同的东西?

时间:2015-08-17 09:22:32

标签: c# concurrency guava

在某些情况下,我真的很喜欢使用Guava's Striped类。

C#中是否存在等效内容?

4 个答案:

答案 0 :(得分:10)

看起来没有直接的等价物,但是有一些无锁的线程安全收集选项(我不确定你想要实现的目标,所以我可以&#39 ;如果它们适用于您的场景,请说。)看看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

答案 1 :(得分:6)

我认为你能做的最好就是实现自己的,因为所有的dotnet框架类型只为整个列表提供了一个lock
要做到这一点,您可以使用GetHashCode()函数,模数(%)与您想要的条带数。并将其用作Tuple<TLock, List<T>>[]的索引,其中TLock可以是System.Threading命名空间中定义的任何类型的锁,T是您要存储/访问的类型。
通过此,您可以决定如何存储条带。有一些选项,如HashSet(因为你已经使用了一些比特来计算条带索引,因此效率很低),SortedSetListArray

顺便说一句,谢谢你提出这个问题,它会帮助我解决我遇到的问题。

答案 2 :(得分:1)

您是否尝试过NuGet中的Tamarind? 它是Google的Guava库的C#端口

答案 3 :(得分:1)

我认为ConcurrentDictionary可以存档类似的结果。

根据他们的文件:

  

所有这些操作都是原子的,并且对于ConcurrentDictionary类的所有其他操作都是线程安全的。唯一的例外是接受委托的方法,即AddOrUpdate和GetOrAdd。对于字典的修改和写入操作,ConcurrentDictionary使用细粒度锁定来确保线程安全。 (对字典的读取操作是以无锁方式执行的。)但是,这些方法的委托在锁外部调用,以避免在锁定下执行未知代码时可能出现的问题。因此,这些代理执行的代码不受操作原子性的影响。

如您所见,读取操作是无锁定的。这将允许您在其他人插入时不阻止线程读取。