在这里插入代码片
volatile变量具备两种特性:
一种是保证该变量对所有线程是可见的,在一个线程修改了变量的值后,新的值对于其他线程是可以立即获取的;第二种是volatile禁止指令重排,即volatile变量不会写入缓存寄存器或者其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。
面试回答:
在JVM中会对我们的java程序进行优化,把我们经常使用的变量保存在缓存中,也就是保存在CPU的寄存器之中,从而避免直接去内存中读取,因为CPU直接从内存中读取数据需要通过总线发送指令给内存,这个速度远远比不上我们的CPU在我们的寄存器直接读取数据,系统这个优化可以大大的提高我们程序运行的效率,但是当遇到多线程的时候,变量的值可能已经被别的线程修改了,而该缓存却没法得知这个数据的变化,从而造成我们线程中读取的数据跟内存中的实际数据不一样,也就是脏数据。
如果使用volatile这个关键字进行修饰的话,系统每一次读取这个数据的时候直接去内存中去取,需要注意的是volatile这个关键字并不能保证原子性,此外会组织编译器对我们程序进行优化,除非很有必要,尽量避免使用volatile这个关键字。
总结起来:volatile这个关键字是通过直接从内存读取数据的方式来避免多线程的情况下读取到脏数据。
同时满足两个条件才能保证线程安全
对变量的写操作不依赖当前值,或者说单纯的变量赋值;
对变量没有包含在具有其他变量的不变式中,也就是说不同的volatile变量之间不能相互依赖,只有在状态真正独立于程序内的其他内容才能使用volatile
voaltile boolean flag = true;