2012-02-13 86 views
2

所以我在这里实现一些缓存层。 Particurally我坚持如何确保线程安全的集合ConcurrentDictionary?

ConcurrentDictionary<SomeKey,HashSet<SomeKey2>> 

我需要确保对HashSet的操作是线程安全的太(ERGO更新是线程安全的)。有没有可能以任何简单的方式,或者我必须在UpdateFactory委托中进行同步?如果答案是肯定的(我认为)以前遇到过这个问题,并且解决了它吗?

我想避免ConcurrentDictionary的ConcurrentDictionary,因为它们分配了很多同步对象,而且我可能在这件事上有大约一百万个条目,所以我想在GC上减少压力。 选择HashSet是因为它保证了插入,删除和访问的不变成本。

上述结构将被用作更大的数据集上的索引,其中以列作为键(SomeKey和Somekey2)非常类似于数据库索引。

+0

你可以继承'HashSet'使其同步(但这可能会违背你使用ConcurrentDictionary >'的原因)。或者,您可以在从ConcurrentDictionary中获取后自己执行同步。这当然是更多的工作。它看起来像你期望的并发,而不必承担开销... – 2012-02-13 02:15:15

+2

最简单的解决方案是使用锁定条带,以确保在集合上的操作是线程安全的。如果您使用可变的非并发Set,则需要锁定读取。否则,将需要一个不可变/持续或并发Set,这会影响内存/写入性能。更具体的结构可能有更多细节,但这是最实用的方法,直到需要更高水平的并发。 – 2012-02-13 03:29:44

+0

@ M.Babcock这不是我不希望并发成本。我只是不想支付价格的n倍。 ConcurrentDictionary已经为我提供了原子读取,并且写入了需要原子值存储在其中的问题(即不变性)。字典为同步化分配4 * Enviroment.ProcessorCount对象,并且如果您有1 000 000个密钥,则每次发生GC级别2时,您都会向第2代添加约32百万个对象。而我的并发水平肯定不是三千万。更像32。 – luckyluke 2012-02-13 15:48:09

回答

1

好吧,所以最后我决定用Immutable set和lock striping去,因为它的实现和理解相当简单。如果我在写入时需要更多的性能(不需要在插入时复制整个哈希集合),我将使用条带化来实现读写器锁定 - 无论如何,这应该很好。 感谢您的建议。

相关问题