栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

.NET中双重检查锁定中对volatile修饰符的需求

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

.NET中双重检查锁定中对volatile修饰符的需求

挥发是不必要的。好吧,**

volatile
用于在变量的读写之间创建内存屏障
lock
使用时,
lock
除了将对块的访问限制在一个线程之外,还会在内的块周围创建内存屏障。
内存屏障使之成为可能,因此每个线程都读取变量的最新值(而不是某些寄存器中缓存的本地值),并且编译器不会对语句进行重新排序。
volatile
不需要使用

*,因为您已经锁定了。

约瑟夫·阿尔巴哈里(Joseph
Albahari)以前所未有的方式
解释了这种东西。

并且一定要查看Jon Skeet的C#实现单例指南。

update
*

volatile
导致对变量的读取为
VolatileRead
s ,对变量的写入为
VolatileWrite
s,这在x86和CLR上的x64上使用来实现
MemoryBarrier
。在其他系统上,它们可能更细粒度。

**仅当您在x86和x64处理器上使用CLR时,我的回答才是正确的。在其他内存模型中,例如在Mono(和其他实现),Itanium64和将来的硬件上,
可能 是正确的。这就是乔恩在“陷阱”中的文章中针对双重检查锁定所指的内容。

为了使代码在内存模型较弱的情况下正常工作,可能需要执行以下操作之一(将变量标记为

volatile
,使用进行读取
Thread.VolatileRead
或插入对的调用)
Thread.MemoryBarrier

据我了解,在CLR(即使是在IA64上),写入也不会重新排序(写入始终具有发布语义)。但是,在IA64上,除非将其标记为易失性,否则可能会将读取重新排序为先于写入。不幸的是,我无权使用IA64硬件,因此我所说的只是猜测。

我还发现这些文章有所帮助:
http://www.preproject.com/KB/tips/MemoryBarrier.aspx

万斯莫里森的文章(一切链接到这一点,它谈论的双重检查锁定)
克里斯brumme的文章
(所有链接到本)
乔·达菲(Joe Duffy):双重检查锁定的残破变体

luis abreu的有关多线程的系列也很好地概述了这些概念
http://msmvps.com/blogs/luisabreu/archive/2009/06/29/multithreading-load-and-
store-reordering.aspx

http:// msmvps。 com / blogs / luisabreu / archive / 2009/07/03 /
multithreading-introducing-memory-
fences.aspx



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/416846.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号