volatile有两个作用:可见性和有序性。
一、volatile可见性:
相比于synchronized的加锁方式来解决共享变量的内存可见性问题,volatile就是更轻量的选择,它没有上下文切换的额外开销。
volatile可以确保对某个变量的更新对其它线程马上可见,一个变量被声明为volatile时,线程在写入变量时不会把值缓存在寄存器或者其它地方,而是会把值刷新回主内存,当其它线程读取共享变量会从主内存重新获取最新值,而不是使用当前线程的本地内存中的值。
例如:
volatile int x = 0;
线程A修改x = 1,修改完之后会把新的值刷新回主内存,线程B读取x的值时,先清空本地内存变量,然后再从主内存获取最新值。
二、volatile有序性
重排序可以分为编译器重排序和处理器重排序,volatile保证有序性就是通过分别限制这两种类型的重排序。
为了实现volatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。
1. 在每个volatile写操作的前面插入一个StoreStore 屏障
2. 在每个volatile写操作的后面插入一个StoreLoad 屏障
3. 在每个volatile读操作的后面插入一个LoadLoad 屏障
4. 在每个volatile读操作的后面插入一个LoadStore 屏障