目录
前言:
volatile
关键字表示被修饰的变量容易变化
被
volatile
关键字修饰的变量读、写操作都会从高速缓存或主内存中读取,来获取变量的相对新值
volatile关键字不会引起上下文切换,故也被成为轻量级锁
正文:
原理:
volatile的作用:
- 保障可见性
- 保障有序性
- 保障写操作的原子性
- 保障long/double型变量的写操作的原子性
不表示赋值操作具有原子性
volatile写操作:
volatile读操作
其中,加载屏障通过冲刷处理器 缓存,使其执行线程(读线程)所在的处理器将其他处理器对共享变量(可能是多个变量)所做的更新同步到该处理器的高速缓存中.
读线程执行的加载屏障和写线程执行的存储屏障配合在一起使得写线程对Volatile变量的写操作以及再在此之前所执行的其他内存操作的结果对读线程可见, 即保障了可见性.
因此, volatile不仅仅保障了volatile变量本身的可见性, 还保障了写线程在更新volatitle变量之前执行的所有操作结果对读线程可见
这种可见性保证类似于锁对可见性的保证, 与锁不同的是 volatile 不具备排他性, 因而它不能保证读线程读取到的这些共享变量的值是最新的, 即读线程读取到这些共享变量的那一刻可能已经有其他写线程更新了这些共享变量的值.
另外获取屏障禁止volatile读操作后之后的任何读, 写操作与volatile读操作进行重排序.因此它保障了volatile读之后的任何操作开始执行之前,写线程对相关共享变量(包括volatile变量和普通变量)的更新已经对当前线程可见.
另外,volatile 关键字也可以被看做给JIT编译器的一个提示, 它相当于告诉JIT编译器相应变量的值可能被其他处理器更改, 从而是JIT编译器不会对相应的代码作出一些优化而导致可见性的问题.
volatile禁止重排序总结
- 写volatile变量操作与该操作之前的任何读、写操作不会被重排序
- 读volatile变量操作与该操作之后的任何读、写操作不会被重排序
volatile变量的开销
读、写都不会导致上下文切换,所以开销比较小