volatile作用、特点
- 线程可见性
- 一个线程修改了volatile修饰的对象,强制失效其他线程的缓存,必须从主存读取。
- 原理:
- lock指令:设置LOCK#信号能保证某个处理器对共享内存的独占使用;
- 使得本CPU的Cache写入内存,该写入动作也会引起别的CPU cache line invalidate。
- 所以通过这样一个空操作,可让前面volatile变量的修改对其他CPU立即可见
- JVM实现:lock指令
- 处理器实现:缓存一致性协议
- 禁止指令重排
- 处理器速度快,内存速度慢;处理器会对没有依赖关系的指令进行重排执行,即不一定会顺序执行;编译器也会有指令重排的实现
- JVM内存屏障:在普通变量和volatile变量之间插入内存屏障保证顺序执行(lock指令)
- volatile与普通变量的重排序规则:
如果第一个操作是volatile读,那无论第二个操作是什么,都不能重排序;
如果第二个操作是volatile写,那无论第一个操作是什么,都不能重排序;
如果第一个操作是volatile写,第二个操作是volatile读,那不能重排序。