为啥 ReadOnlyDictionary 不是线程安全的?

Posted

技术标签:

【中文标题】为啥 ReadOnlyDictionary 不是线程安全的?【英文标题】:Why isn’t ReadOnlyDictionary thread-safe?为什么 ReadOnlyDictionary 不是线程安全的? 【发布时间】:2012-11-20 23:18:57 【问题描述】:

我正在寻找一个可以从多个线程访问的只读字典。虽然 ConcurrentDictionary 公开了这些功能,但我不希望有开销和奇怪的 API。

.Net 4.5 在提供这样一个类时,文档指出只有静态调用是安全的。

我想知道为什么?

【问题讨论】:

从 Microsoft 文档复制:线程安全 ConcurrentDictionary 的所有公共和受保护成员都是线程安全的,可以从多个线程同时使用。 @KenCheung:尚不清楚您的评论为何相关。该问题表明OP已经知道ConcurrentDictionary<,>,但正在询问ReadOnlyDictionary<,>的安全性。 【参考方案1】:

ReadOnlyDictionary 只是任何其他字典的包装器。因此,它仅与底层字典一样是线程安全的。

特别是,如果有一个线程正在修改底层字典,而另一个线程从包装器中读取,则无法保证安全。

如果你想要一个ReadOnlyDictionary,它从所有角度实际上是不可变的,你可以创建一个原始字典的克隆,围绕它创建一个ReadOnlyDictionary包装器,然后不保留引用到任何地方的克隆。随着 only 读取操作的进行,它应该是线程安全的。当然,如果键或值类型是可变的,则需要担心第二级“线程不安全”。

【讨论】:

只是一个澄清。只读并不意味着线程安全。如果字典根据读取使用情况重新排列项目怎么办? BCL 字典不这样做(AFAIK),但我在某处读到 Scripting.Dictionary 将最后读取的项目移动到存储桶中的第一个位置。 @adrianm:是的,这是真的。但是你可以包装一个从未修改过的System.Collections.Generic.Dictionary那个就可以了。 关于“应该”——它并不能像我们期望的那样严格保证是线程安全的,对吧?如果这个答案是准确的,我们在这里进入“非官方线程安全”行为 - ***.com/a/28960891 @MaxBarraclough:Dictionary 文档明确指出“只要不修改集合,Dictionary<TKey,TValue> 可以同时支持多个读取器。”因此,如果ReadOnlyDictionary 包装了Dictionary,并且在初始化后从未修改过,我认为这很好。 @JonSkeet 完美。我错过了。

以上是关于为啥 ReadOnlyDictionary 不是线程安全的?的主要内容,如果未能解决你的问题,请参考以下文章

.Net中ReadOnlyDictionary和查找之间的区别[关闭]

GeometryRenderer 为啥渲染线,而不是三角形

将 Dictionary<TKey, List<TValue>> 转换为 ReadOnlyDictionary<TKey, ReadOnlyCollection<T

为啥启用/禁用 A20 线

为啥我用DXF文件导入到PADS 2007中后 板框图不是2D线

为啥stm32电脑识别不了