C#从一个线程设置字典对象,从另一个线程获取字典对象是否是线程安全的
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C#从一个线程设置字典对象,从另一个线程获取字典对象是否是线程安全的,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2230字,纯文字阅读大概需要4分钟。
内容图文
![C#从一个线程设置字典对象,从另一个线程获取字典对象是否是线程安全的](/upload/InfoBanner/zyjiaocheng/669/d1b77d74aa554182843ad795b94d0f0a.jpg)
假设我们有一个奇怪的类,其中包含
>公共属性ReadOnlyDictionary< string,string>地图{get;私人套装;}
>方法更新,该方法在调用时会重置地图字典.
从一个线程调用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的执行不是原子的?
解决方法:
“线程安全”是一个模糊的术语.维基百科将线程安全代码定义为:
Thread-safe code only manipulates shared data structures in a manner
that ensures that all threads behave properly and fulfill their design
specifications without unintended interaction
因此,在不知道设计规范的情况下,我们不能说某些代码是“线程安全的”,其中包括该代码的实际使用方式.
该代码在某种意义上是“线程安全的”,即任何线程都无法观察处于损坏或部分状态的Example对象.
引用分配是原子的,因此读取Map的线程只能读取其中的一个或另一个,而不能观察Map的部分或中间状态.因为Map的键和值都是不可变的(字符串),所以整个对象是不可变的,并且从Map属性读取对象后,可以安全地由多个线程使用.
但是,请执行以下操作:
var example = GetExample();
if (example.Map.ContainsKey("key")) {
var key = example.Map["key"];
}
当然不是线程安全的,因为作为一个整体,Map对象可能在检查和从字典中读取之间发生了变化,旧版本包含“键”键,而新版本则没有.另一方面,这样做:
var example = GetExample();
var map = example.Map;
if (map.ContainsKey("key")) {
var key = map["key"];
}
很好任何不依赖example.Map的代码在两次读取之间保持不变应该是“安全的”.
因此,您必须确保给定的代码在您的特定用例中是“线程安全的”.
请注意,在这里使用ConcurrentDictionary绝对没有用.由于您的字典是只读的-从多个线程读取它已经很安全.
更新:注释中提出的有效观点是ReadOnlyDictionary本身不能保证基础数据不会被修改,因为ReadOnlyDictionary只是常规可变字典的包装.
但是,在这种情况下,您将通过非共享字典实例(从ToDictionary接收)在Update方法中创建ReadOnlyDictionary,该字典实例仅用于将其包装在ReadOnlyDictionary中,而不能用于其他任何事情.这是一种安全的用法,因为除了ReadOnlyDictionary本身之外,没有代码可以访问可变基础字典,而只读字典阻止对其进行修改.只要没有写操作,即使从常规Dictionary中读取也是线程安全的.
内容总结
以上是互联网集市为您收集整理的C#从一个线程设置字典对象,从另一个线程获取字典对象是否是线程安全的全部内容,希望文章能够帮你解决C#从一个线程设置字典对象,从另一个线程获取字典对象是否是线程安全的所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。