Volatile是神马

0 篇文章 0 订阅

曾经面试被问到过一次Volatile的含义, 因为当时的一段时间一直比较多的用java, 单只回答了java处的含义, 记不太清楚C中的内涵了, 这次正好又查东西链接到相关的资料, 就记下来复习复习:)


C/C++中的作用:

  • 允许访问memory mapped设备(比如,一个指针,指向的是一个硬件寄存器)
  • 允许在setjmp和longjmp之间使用该变量 (长跳转之后该变量还有意义)
  • 允许在signal handler中使用sig_atomic_t的变量 (通常这个类型的变量也会声明为volatile, 参考资料3)

通常来说, 任何会被异步更新的变量都应该被用volatile声明. 但是这里不包扩CPU会把变量保存到register中的情况.

它告诉编译器生成的代码中,对该变量每次使用的时候都会reload它,而不是只拿已经load到register中值来用.

对volatile变量的操作不是原子的, 使用它们的线程也不能保证相互之间的顺序性(即如果几个线程不加保护的使用它,不能保证操作它的顺序).

请注意, 如果使用-O2,通常gcc不会对没有声明为volatile的变量在每次使用时,从内存中重新载入值到寄存器, 而只是用寄存器中的值.

当然,volatile的性能肯定比register差, 所以如果不需要使用volatile, 请不要滥用.


JAVA中:

它与C/C++的作用很不相同:

  • 所有的java版本中,对一个volatile变量有一个全局的读写顺序. 这意味着每个访问该volatile变量的读操作总是返回当前的值,而不是使用的是一个cache的值. 然而, 它与C/C++中一样,如果是在多线程的环境下,多个线程对同一个变量的读写之间的顺序是不被保证的.
  • 在java 5及其之后的版本中, 实现了对volatile变量的读写操作的获得并释放的类似mutex的动作.

从以上可以看出, 使用volatile变量比使用lock要快, 但是它不适用于一些场合.  在java 5中对其有所表现; 例如, double-checked locking现在工作的正确了.
// Works with acquire/release semantics for volatile
// Broken under Java 1.4 and earlier semantics for volatile
class Foo {
    private volatile Helper helper = null;
    public Helper getHelper() {
        Helper result = helper;
        if (result == null) {
            synchronized(this) {
                result = helper;
                if (result == null) {
                    helper = result = new Helper();
                }
            }
        }
        return result;
    }
 
    // other functions and members...
}


参考资料:

http://en.wikipedia.org/wiki/Volatile_variable

http://www.kcomputing.com/volatile.html

http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值