c# – 延迟加载和使用Thread.MemoryBarrier
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 延迟加载和使用Thread.MemoryBarrier,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1554字,纯文字阅读大概需要3分钟。
内容图文
![c# – 延迟加载和使用Thread.MemoryBarrier](/upload/InfoBanner/zyjiaocheng/808/a8e4aaa78a21475f8d89dc9db755088c.jpg)
在设计具有对另一个对象的引用的类时,仅在第一次使用时创建引用的对象可能是有益的,例如,使用延迟加载.
我经常使用这种模式来创建一个延迟加载的属性:
Encoding utf8NoBomEncoding;
Encoding Utf8NoBomEncoding {
get {
return this.utf8NoBomEncoding ??
(this.utf8NoBomEncoding = new UTF8Encoding(false));
}
}
然后我在浏览BCL的源代码时遇到了这段代码:
Encoding Utf8NoBomEncoding {
get {
if (this.utf8NoBomEncoding == null) {
var encoding = new UTF8Encoding(false);
Thread.MemoryBarrier();
this.utf8NoBomEncoding = encoding;
}
return this.utf8NoBomEncoding;
}
}
据我所知,这些都不是线程安全的.例如.可以创建多个编码对象.我完全明白了,如果创建了额外的Encoding对象,那就不是问题了.它是不可变的,很快就会被垃圾收集.
但是,我真的很想知道为什么Thread.MemoryBarrier是必要的,以及第二个实现与多线程场景中的第一个实现有何不同.
显然,如果线程安全是一个问题,最好的实现可能是使用Lazy< T>:
Lazy<Encoding> lazyUtf8NoBomEncoding =
new Lazy<Encoding>(() => new UTF8Encoding(false));
Encoding Utf8NoBomEncoding {
get {
return this.lazyUtf8NoBomEncoding.Value;
}
}
解决方法:
这段代码将是一场没有内存障碍的灾难.仔细看看这些代码行.
var encoding = new UTF8Encoding(false);
Thread.MemoryBarrier();
this.utf8NoBomEncoding = encoding;
现在,想象一些其他线程看到最后一行的效果,但没有看到第一行的效果.那将是一场彻底的灾难.
内存屏障确保任何看到编码的线程都能看到其构造函数的所有效果.
例如,没有内存屏障,第一行和最后一行可以在内部优化(大致)如下:
1)分配一些内存,在this.utf8NoBomEncoding中存储指向它的指针
2)调用UTF8Encoding构造函数以使用有效值填充该内存.
想象一下,如果在步骤1和步骤2之间运行另一个线程并通过此代码.它将使用尚未构建的对象.
内容总结
以上是互联网集市为您收集整理的c# – 延迟加载和使用Thread.MemoryBarrier全部内容,希望文章能够帮你解决c# – 延迟加载和使用Thread.MemoryBarrier所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。