volatile关键字 C++与Java的区别你知道吗?

volatile

volatile这个单词在英文之中的意思是:易变的,不稳定的的含义。

Java volatile

在Java中有volatile关键字,Java之中volatile的作用是:

  • 确保内存可见性:读写变量具有全局有序性,保证当前线程读到的值是内存中最新的,而不是当前线程中缓存中的值。但是volatile关键字并不保证线程读写变量的相对顺序,所以适用场景有限。

  • 禁止指令重排序(happens-before原则):指令重排序是JVM为了提高运行程序的效率,在不影响单线程执行结果的前提下,对指令的执行过程进行优化。注意是单线程,多线程下指令重排序就可能会影响结果。

注意Java的有序性是指:

  • 在当前线程读写操作前的修改操作的值对当前操作可见。
  • 在进行指令优化时,不能将在对volatile变量访问的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行。
C++ volatile

A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided.

C++中的volatile有三个性质:

  • 易变的
  • 不可优化的
  • 顺序性

volatile相当于显式的要求编译器禁止对 volatile 变量进行优化,并且要求每个变量赋值时,需要显式从寄存器%eax拷贝。volatile 关键字在嵌入式编程之中会需要用到,在特定环境下,寄存器的变量可能会发生变化。volatile 所以声明了寄存器部分的数据是『易变的』,需要防止编译器优化变量,强制载入寄存器。

C++中的volatile的顺序性是指:

  • C/C++ Volatile变量,与非Volatile变量之间的操作,是可能被编译器交换顺序的。
  • C/C++ Volatile变量间,编译器是能够保证不交换顺序的。

C/C++ Volatile关键词,并不能用于构建happens-before语义,因此在进行多线程程序设计时,要小心使用volatile,不要掉入volatile变量的使用陷阱之中。

但是如果需要实现类似 Java 之中 volatile 的效果呢?可以在代码之中显式插入内存屏障,让 CPU 强制刷新寄存器的变量到内存之中。

举个例子:

int n = 1;                                                                                         
int main() {
    volatile int x = n;
    asm volatile("" ::: "memory");
    volatile int y = n;
    return 0;
}
发布了118 篇原创文章 · 获赞 5 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/LU_ZHAO/article/details/104802876