为啥 ReadOnlyDictionary 不是线程安全的?
Posted
技术标签:
【中文标题】为啥 ReadOnlyDictionary 不是线程安全的?【英文标题】:Why isn’t ReadOnlyDictionary thread-safe?为什么 ReadOnlyDictionary 不是线程安全的? 【发布时间】:2012-11-20 23:18:57 【问题描述】:我正在寻找一个可以从多个线程访问的只读字典。虽然 ConcurrentDictionary 公开了这些功能,但我不希望有开销和奇怪的 API。
.Net 4.5 在提供这样一个类时,文档指出只有静态调用是安全的。
我想知道为什么?
【问题讨论】:
从 Microsoft 文档复制:线程安全 ConcurrentDictionaryConcurrentDictionary<,>
,但正在询问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和查找之间的区别[关闭]
将 Dictionary<TKey, List<TValue>> 转换为 ReadOnlyDictionary<TKey, ReadOnlyCollection<T