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

  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()方法的

posted @ 2010-06-04 00:27  new 维生素C.net()  阅读(2601)  评论(1编辑  收藏  举报