2012-02-13 92 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去,因爲它的實現和理解相當簡單。如果我在寫入時需要更多的性能(不需要在插入時複製整個哈希集合),我將使用條帶化來實現讀寫器鎖定 - 無論如何,這應該很好。 感謝您的建議。

相關問題