volatile关键字可见性问题

Volatile关键字

保证共享变量可见性
多个线程,读取和写,读取线程不能及时读取到改变的值
实现跨线程可见性,使用volatile关键字
指令lock,在修改变量属性时候加lock,如果不加volatile关键字,这个lock指令是不存在的,这就是区别,多个汇编指令lock,

可见性到底是什么?

硬件层面
最核心组件,cpu,内存,磁盘,速度差异,
绝大部分程序计算都有依靠,
最大化cpu资源
1.cpu增加高速缓存
2.引入线程,进程
3.指令优化,指令重排序
主内存和cpu之间加入cpu高速缓存,cpu高速缓存分为L1,L2,L3
L1,L2是cpu私有。L1分为数据缓存和指令缓存
L3缓存是多个cpu共享的
数据同步到主内存,同步之前其他cpu拿到的是旧值,缓存一致性问题导致的,高速缓存会带来缓存一致性问题,cpu层面会解决,通过两种方案,缓存锁,总线锁。
如何实现缓存锁,基于缓存一致性协议(MESI),达到缓存数据一致

但是没有解决可见性,MESI协议会带来问题,重排序带来可见性问题,硬件方面无法完全解决可见性问题。
CPU提供内存屏障指令,在程序中可以加入内存屏障,从而达到可见性

CPU三种屏障,写屏障,读屏障,全屏障。

volatile里面lock(缓存锁)指令相当于内存屏障指令

jmm层面

可见性根本原因,高速缓存,和重排序,所以还是解决重排序问题
volatile关键字可以解决这个问题
语言级别抽象内存模型

jmm解决有序性和可见性
jmm通过内存屏障禁止重排序

分为主内存和工作内存
如何解决可见性和有序问题
volatile,synchronized,final,happens-before
顺序的不一致就会产生可见性问题

jmm内存屏障
语言级别内存屏障,
ACC_VOLAITLE这个判断是否加了volatile关键字
被volatile修饰后,都会有个storeload操作,加屏障。解决可见性问题
volatile关键字可见性问题_第1张图片

Happens-before规则

volatile规则
A happens-before B一个结果对另一个结果可见,

jmm哪些操作会建立happens-before原则
程序的顺序规则

你可能感兴趣的:(volatile,java)