原 java volatile禁止指令重排
版权声明:本文为博主原创文章,请尊重他人的劳动成果,转载请附上原文出处链接和本声明。
本文链接:https://www.91mszl.com/zhangwuji/article/details/1126
代码如下:
package com.mszl.thread;
/**
* 功能:volatile禁止指令重排
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class Volatile3 {
int a=0;
boolean flag=false;
public void aa(){
a=1; // 代码1
flag=true; // 代码2
}
// 多线程环境中线程交替执行,由于编译器优化重排的存在,两个线程中使用的变量能否保证一致性是无法确定的,结果无法预测。
public void bb(){
if(flag){
a=a+5;
System.out.println(a);
}
}
}
案例中,在多线程环境下有以下两种情况:
(1)在aa()方法中,先执行代码1即 a=1,flag=true; 在执行bb()方法,flag=true,则输出a=6
(2)在aa()方法中,先执行代码2即 flag=true,还没来得及执行a=1,在执行bb()方法,a初始化为0,则输出a=5
总结:volatile实现了禁止指令重排优化,从而避免多线程环境下程序出现乱序执行的现象。
内存屏障(Memory Barrier)又称内存栅栏,是一个CPU指令,它的作用如下:
(1)保证特定操作的执行顺序。
(2)保证某些变量的内存可见性(利用该特性实现volatile的内存可见性)
由于编译器和处理器都能执行指令重排优化,如果在指令间插入一条Memory Barrier 则会告诉编译器和CPU,不管什么指令都不能和这条Memory Barrier 指令重排序,也就是说通过插入内存屏障禁止在内存屏障前后的指令执行重排序优化。内存屏障另外一个作用是强制刷出各种CPU的缓存数据,因此任何CPU上的线程都能读取到这些数据的最新版本。
2019-11-24 17:41:05 阅读(1389)
名师出品,必属精品 https://www.91mszl.com
博主信息