我正在考虑从 Dictionary 迁移到 ConcurrentDictionary 以实现多线程环境。
具体到我的用例,kvp 通常是<string, List<T>>
- 我需要注意什么?
- 如何成功实现线程安全?
- 如何管理在不同线程中读取键和值?
- 如何管理不同线程中键和值的更新?
- 如何管理在不同线程中添加/删除键和值?
我需要注意什么?
取决于您想要实现的目标:)
如何管理在不同线程中读取键和值?
如何管理不同线程中键和值的更新?
如何管理在不同线程中添加/删除键和值?
这些应该由字典本身以线程安全的方式处理。有几个警告:
-
接受工厂的功能如ConcurrentDictionary<TKey,TValue>.GetOrAdd(TKey, Func<TKey,TValue>)
就工厂调用而言不是线程安全的(例如,如果多个线程尝试获取或添加项目,字典不保证工厂只会被调用一次)。引用文档:
所有这些操作都是原子的,并且相对于系统上的所有其他操作来说都是线程安全的ConcurrentDictionary<TKey,TValue>
班级。唯一的例外是接受委托的方法,即AddOrUpdate
and GetOrAdd
。对于字典的修改和写入操作,ConcurrentDictionary<TKey,TValue>
使用细粒度锁定来保证线程安全。 (字典上的读取操作以无锁方式执行。)但是,这些方法的委托是在锁外部调用的,以避免在锁下执行未知代码时可能出现的问题。因此,这些委托执行的代码不受操作原子性的影响。
-
在您的特定情况下值 -List<T>
本身不是线程安全的,因此虽然字典操作将是线程安全的(上一点除外),但使用值本身改变操作 - 不会,请考虑使用类似的东西ConcurrentBag
或切换到IReadOnlyDictionary
.
-
就我个人而言,我会谨慎地通过显式实现的接口来使用并发字典,例如IDictionary<TKey, TValue>
和/或索引器(可能导致读取-更新-写入场景中的竞争条件)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)