volatile的底层实现原理是内存配置
- 对volatile变量的写指令后会加入写屏障
- 对volatile变量的读指令前会加入读屏障
如何保证可见性
写屏障 保证在该屏障之前的,对共享变量的改动,都同步到主存当中,不光光是对ready同步的,而且会对上边所有的代码进行同步
public void actor2(I_Result r){
num = 2;
ready = true;
// 此处存在写屏障
}
读屏障保证在该屏障之后,对共享变量的读取,加载的是主存中最新的数据
public void actor1(I_Result r) {
// 读屏障
if(ready){
r.r1 = num + num;
} else{
r.r1 = 1;
}
}
如何保证有序性
写屏障会确保指令重排序时,不会将写屏障之前的代码排在写屏障之后
public void actor2(I_Result r){
num = 2;
ready = true;
// 此处存在写屏障
}
读屏障会确保指令重排序时,不会将读屏障之后的代码排在读屏障之前
public void actor1(I_Result r) {
// 读屏障
if(ready){
r.r1 = num + num;
} else{
r.r1 = 1;
}
}
不能解决指令交错
- 写屏障仅仅是保证之后能读到的是最新结果,但不能保证读跑到他前边去
- 而有序性也仅仅保证了本线程内的相关代码不会发生重排序