我有四级数据结构定义如下:
Dictionary<Type1, Dictionary<Type2, Dictionary<Type3, List<Type4>>>>
整个事情被封装在一个同样保持线程安全的类中。目前它只是在读取/操作数据时锁定整个集合(读取比写入更常见)。
我在考虑将Dictionary
替换为ConcurrentDictionary
,将List
替换为ConcurrentBag
(不必订购其商品)。
如果我这样做,我可以消除锁定并确保并发集合能够正常工作吗?
答案 0 :(得分:6)
我差不多晚了一年......但是如果有人发现自己与MatějZábský处于类似的位置,请问自己:
您可以改用Dictionary<Tuple<Type1, Type2, Type3>, List<Type4>>
吗?
使用起来相当容易,并且考虑到散列表(即字典)是O(1)数据结构,其中有一个有点沉重的常量组件(如果你转移到ConcurrentDictionary
则更是如此)它很可能表现得更快。它也会使用更少的内存,并且转换为ConcurrentDictionary
非常简单。
当然,如果您需要枚举给定Type2
键的所有给定Type1
,嵌套词典可能就是这样。但这是一项要求吗?
答案 1 :(得分:4)
并发集合将防止数据损坏和崩溃,但代码在语义上不等于您当前的代码。例如,如果您迭代其中一个并发字典some of the items may belong to different updates:
从中返回的枚举器 字典可以安全地同时使用 读取和写入 字典,但它没有 代表一个时刻的快照 词典。内容暴露 通过调查员可能包含 对字典做出的修改 在调用GetEnumerator之后。
如果您想保持现在的确切行为,但节省锁定成本,您可能希望锁定ReaderWriterLockSlim,这尤其适用于读取次数多于写入次数的情况。