Volatile及其实现
相关的CSDN博客:
1、可见性:
Java内存模型规定:所有变量都需要存储在主内存中,线程工作内存保存了变量在主内存中的副本,线程对变量的所有操作都在工作内存中进行,执行结束后在同步到主内存中去。这里必然会存在时间差,在这个时间差内,该线程对副本的操作,对于其他线程是不见的,从而造成了可见性问题。
2、指令重排序
JVM对代码进行编译优化,导致代码可能并不是按照代码编写顺序执行,而是按照JVM进行编译优化后的顺序执行。指令重排序对并发编程安全性有很大影响,所以提供了一些happens-before规则定义一些禁止编译优化的场景。
3、volatile的作用
保证共享变量的可见性:使用volatile修饰的变量,任何线程对其进行操作都是在主内存中进行的,不会产生副本,从而保证共享变量的可见性。
防止局部指令重排序:happens-before规则中的volatile变量规则规定了一个线程先去写一个volatile变量,然后一个线程去读这个变量,那么这个写操作的结果一定对读的这个线程可见。
4、volatile如何防止指令重排序
volatile是通过内存屏障来防止指令重排序的。
硬件层面的内存屏障分为Load Barrier 和 Store Barrier即读屏障和写屏障。
对于Load Barrier来说,在指令前插入Load Barrier,可以让高速缓存中的数据失效,强制从新从主内存加载数据。对于Store Barrier来说,在指令后插入Store Barrier,能让写入缓存中的最新数据更新写入主内存,让其他线程可见。
volatile防止指令重排序具体步骤:
在每个volatile写操作的前面插入一个StoreStore屏障。
在每个volatile写操作的后面插入一个StoreLoad屏障。
在每个volatile读操作的后面插入一个LoadLoad屏障。
在每个volatile读操作的后面插入一个LoadStore屏障
全部评论
(0) 回帖