volatile关键字
volatile主要作用是保证可见性以及有序性 (原子性由锁保证)
可见性
JMM | Java Memory Model
- java内存模型定义了线程和主线程直接的抽象关系,线程之间的共享变量存储在主内存中,每个线程都有一个私有的本地内存,本地内存存储了共享变量的副本
- 可能出现的可见性问题,即线程A修改了本地内存未及时刷新到主内存,从而导致其它线程使用的共享变量值不是最新的
使用 volatile 修饰共享变量后,每个线程要操作变量时会从主内存中将变量拷贝到本地内存作为副本,当线程操作变量副本并写回主内存后,会通过
CPU 总线嗅探机制
告知其他线程该变量副本已经失效,需要重新从主内存中读取
有序性
- 禁止指令重排
- 什么是指令重排:处理器为了提高程序运行效率,可能会对代码进行优化,它可能在不改变执行结果的前提下修改程序中各个语句执行顺序(重排不会影响单线程的执行,但是可能影响并发执行的正确性)
- 多线程环境下线程交替执行,由于编译器优化,两个线程中使用的变量是否保证一致性是无法确定的,导致结果无法预测
//如果线程1 执行a方法先执行了语句2,线程2进来执行b方法时,拿到的a 还是0
pubilc class Demo{
int a = 0;
boolean flag = false;
public void a(){
a = 1; //语句1
flag = true; //语句2
}
public void b(){
if(flag){
a = a + 5;//语句3
}
}
}