【发布时间】:2018-03-26 19:19:16
【问题描述】:
假设我们有一些包含
的 strange 类- 公共财产
ReadOnlyDictionary<string, string> Map {get; private set;} - 方法
Update在调用时重新设置Map字典。
从一个线程调用方法Update并从另一个线程获取Map是线程安全的吗?
public class Example
{
public ReadOnlyDictionary<string, string> Map{ get; private set; }
public void Update(IEnumerable<KeyValuePair<string, string>> items)
{
Map = items
.ToLookup(x => x.Key)
.ToDictionary(x => x.Key, x => x.First())
.ToReadOnlyDictionary(); // helper method
}
}
是否有可能会出现我们调用 Map getter 并返回 null 或处于不良状态的情况,因为 setter 执行不是原子的?
【问题讨论】:
-
取决于您对
Example实例的处理,您在使用Map和Set时是否lock? -
@TimSchmelter no
-
Map是一个引用类型,对引用的赋值是原子的——所以它的一部分是线程安全的。但是,如果另一个线程正在修改items而Update()正在运行,那么您将度过一段糟糕的时光。 -
@sleepy 引用分配保证是原子的。
Map将返回旧值或ToReadOnlyDictionary返回的新值。 -
您将遇到的唯一问题是,使用它的代码是否依赖于每次访问属性时都获得相同的
Map。例如,它可能使用ContainsKey然后[]来查找密钥。从技术上讲,这不是线程安全问题 - 但它可能会引发异常(因为第一个Map可能有某个键,但第二个Map可能没有)。
标签: c# .net thread-safety volatile