Volatile
volatile确保对一个变量的更新以一种可预见的形式告知其它线程,意思是volatile保证了可见性,不保证原子性。而且编译器对volatile变量的操作不会是在寄存器或者缓存中,而是内存中,所以它每次取得就是最新值.
例如:
public class VolatileTest extends Thread {
boolean flag = false;
int i=0;
@Override
public void run() {
while (!flag){
i++;
}
}
public static void main(String[] args)throws Exception{
VolatileTest vt = new VolatileTest();
vt.start();
Thread.sleep(3000);
vt.flag=true;
System.out.print("i的值为:"+vt.i);
}
}
预期结果:
打印结果,程序结束
实际结果:
结果是打印了,但是程序没有结束
为什么没结束,这其实要理解操作系统的运行原理,为了提高效率,cpu会有自己的缓存,如果cpu判断到是操作同一个地址的值,那么它是去操作缓存中的数据,然后在同步到内存中,而其它线程拿的还是缓存中的数据,不是内存中的数据,所以拿到的不是最新值.
给变量加volatile
volatile boolean flag = false;
结果:
输出i的值,线程退出
原因:因为加了volatile,所有的线程在内存中取数据,而不是缓存中,所以可拿到最新的值
volatile一般的应用场景:
1.写入变量并不依赖变量的当前值,或者确保只有单一的线程修改变量的值
2.变量不需要和其它的状态变量共同参与不变约束
3.访问变量时,不需要其它的原因需要加锁