谈一下你对 volatile 关键字的理解?
volatile是一个java虚拟机提供的轻量级的同步机制,保证了对变量的操作可见性和禁止指令重排,但不保证原子性。
原子性:程序中的所有操作是不可中断的,要么全部执行成功要么全部执行失败。
可见性:指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。(可补充介绍java的内存模型(JMM))。
指令重排:处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证单线程程序最终执行结果和代码顺序执行的结果是一致的。
可见性,指令重排实例:
https://www.cnblogs.com/qdhxhz/p/9179725.html
你在哪些地方用到过volatile?
1、单例模式(双重检查锁DCL)
菜鸟教程--https://www.runoob.com/design-pattern/singleton-pattern.html
2、读写锁手写缓存
3、CAS JUC包中大量使用volatile
volatile底层的实现机制?
如果把加入volatile关键字的代码和未加入volatile关键字的代码都生成汇编代码,会发现加入volatile关键字的代码会多出一个lock前缀指令。
lock前缀指令实际相当于一个内存屏障,内存屏障提供了以下功能:
1 . 重排序时不能把后面的指令重排序到内存屏障之前的位置
2 . 使得本CPU的Cache写入内存
3 . 写入动作也会引起别的CPU或者别的内核无效化其Cache,相当于让新写入的值对别的线程可见。
Synchronized与volatile区别
volatile只能修饰变量,synchronized可以修饰变量,方法以及代码块
volatile在多线程中不会存在阻塞问题,synchronized会存在阻塞问题
volatile能保证数据的可见性,但不能完全保证数据的原子性,synchronized即保证了数据的可见性也保证了原子性
volatile解决的是变量在多个线程之间的可见性,而sychroized解决的是多个线程之间访问资源的同步性
参考
面试官必问的8道volatile关键字命题,你答对了吗?