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

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

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

我想知道为什么?

【问题讨论】:

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

标签: concurrency dictionary thread-safety immutability .net-4.5


【解决方案1】:

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

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

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

【讨论】:

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