.net里为什么尽量避免Volatile关键字

本文探讨了在多线程环境中使用volatile关键字的作用及其局限性,并对比了volatile与MemoryBarrier在解决指令乱序问题上的差异。同时介绍了volatile如何保证线程间的可见性和指令顺序性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 需要应用的场景往往是多线程,多,是指多于2个。应用场景很重要,如果那volatile修饰一个用于累加的计数器,那是很糟糕的,它本身不是用来设计做这个。在.net中应该去找Interlocked帮忙。volatile的作用是它可以保证线程之间的可见性(可以理解为1号线程写完了后2号负责读的线程是可见的,所以2号读线程始终可以得到最新的值)和指令的顺序性(专治乱序问题,weak ordering)
  2. volatile与指令序列有着孽缘,比如说对两个变量的两条赋值语句并不一定是按照这个顺序来执行的。同时,对cpu来讲,CPU的Lx缓存在x86/x64上是保持一致的(x64兼容x86,所以脾气跟x86一样),而在IA64是每个CPU独立维护自己的Lx缓存。volatile的作用是清掉这个Lx缓存,直接指向内存。然后自己用volatile read和volatile write去操作数据。
  3. Volatile并不是想象中的那么高效。很多文章总拿Volatile和lock去比,那当然是不具备可比性的。最早我们都讨论singleton实现的时候使用double-check机制,利用volatile,其实不如用MemoryBarrier合算。MemoryBarrier就是为惩治乱序问题而诞生的。Monitor、Mutex啥的都是基于保证Lx缓存的同步来做到的。

结论:如果要维护支持乱序指令的cpu上需要保证某个简单操作不会因为乱序问题而遭受影响的话,那使用volatile。但是这种情景如果还要追求性能的话,别相信别人的话,先去试试MemoryBarrier。

volatile并不保证thread-safe,这个例子可以看到:

image

MSDN上对于volatile的说明是:

The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock statement to serialize access

最后,Thread类有个VolatileRead()方法的

转载于:https://www.cnblogs.com/fanweixiao/archive/2010/06/04/1751112.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值