System.Collections.Concurrent.ConcurrentDictionary的MSDN文档说:
螺纹安全
ConcurrentDictionary<TKey, TValue>的所有公共和受保护成员都是线程安全的,可以从多个线程并发使用。但是,通过ConcurrentDictionary<TKey, TValue>实现的一个接口(包括扩展方法)访问的成员,不能保证是线程安全的,调用方可能需要同步。
(强调地雷)
这似乎自相矛盾。“所有成员都是线程安全的,但成员有时并不是线程安全的。”
我确实理解,扩展方法当然不能保证线程安全。
但是,“通过其中一个接口访问”是什么意思呢?TryGetValue ( IDictionary<TKey, TValue>接口的一个成员)线程安全吗?
发布于 2016-07-12 08:07:31
请注意文档中涉及显式接口实现的部分。这个类实现IDictionary.Add。此方法不是类的公共或受保护成员,但可以通过IDictionary接口访问。正是这些成员没有得到线程安全的保证。
发布于 2016-07-12 08:21:02
因为显式与隐式接口实现。
如果您查看一下ConcurrentDictionary,您可能会发现有一些方法显式地实现了接口(比如object IDictionary.this[object key]),尽管在内部调用相同操作的线程安全版本,但这种行为在将来可能会发生变化。
把它看作是责任的划分:如果我(作为一个类)接收到ConcurrentDictionary<TKey, TValue>的一个实例,我知道以线程安全的方式执行操作是该实例的责任。
但是,如果我(再次作为一个类)接收到IDictionary<TKey, TValue>的一个实例,那么我应该知道是否应该存在线程安全问题。如果没有这样的顾虑,我只使用字典,但如果需要线程安全,那么以线程安全的方式执行所有操作是,我的责任,。
发布于 2016-07-12 07:58:54
文献资料中有一个特定的部分,说明在ConcurrentDictionary<TKey, TValue>中并非所有东西都是线程安全的。
对于
ConcurrentDictionary<TKey, TValue>类上的所有其他操作,所有这些操作都是原子的,并且是线程安全的。唯一的例外是接受委托的方法,即AddOrUpdate和GetOrAdd。对于对字典的修改和写操作,ConcurrentDictionary<TKey, TValue>使用细粒度锁定来确保线程安全。(字典上的读操作以无锁的方式执行。)但是,这些方法的委托在锁之外被调用,以避免在锁下执行未知代码时可能出现的问题。因此,这些委托执行的代码不受操作的原子性的限制。
所以有一些一般的排除和一些特定于ConcurrentDictionary<TKey, TValue>的情况
AddOrUpdate和GetOrAdd上的委托不是在线程安全问题上调用的。https://stackoverflow.com/questions/38323009
复制相似问题