我们这里,就说说他最关键的几个作用是啥?
第一,一旦data变量定义的时候前面加了volatile来修饰的话,那么线程1只要修改data变量的值,就会在修改完自己本地工作内存的data变量值之后,强制将这个data变量最新的值刷回主内存,必须让主内存里的data变量值立马变成最新的值!
整个过程,如下图所示:
第二,如果此时别的线程的工作内存中有这个data变量的本地缓存,也就是一个变量副本的话,那么会强制让其他线程的工作内存中的data变量缓存直接失效过期,不允许再次读取和使用了!
第三,如果线程2在代码运行过程中再次需要读取data变量的值,此时尝试从本地工作内存中读取,就会发现这个data = 0已经过期了!
此时,他就必须重新从主内存中加载data变量最新的值!那么不就可以读取到data = 1这个最新的值了!整个过程,参见下图:
volatile主要作用是保证可见性以及有序性, 但是volatile是不能保证原子性的!
volatile与内存屏障
volatile重排序规则表
为了实现volatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。
JMM基于保守策略的JMM内存屏障插入策略:
1.在每个volatile写操作的前面插入一个StoreStore屏障
2.在每个volatile写操作的后面插入一个SotreLoad屏障
3.在每个volatile读操作的后面插入一个LoadLoad屏障
4.在每个volatile读操作的后面插入一个LoadStore屏障