目录
volatile的作用
保证变量可见性
防止指令重排序 : 例子:双重校验锁的懒汉式单例模式
实现原理
如何保证可见性
java通过几种原子操作完成工作内存和主内存的交互,volatile规定 load之前必须read,这样保证每次读的时候会从主存中读取。
Java变量的读写
Java通过几种原子操作完成工作内存
和主内存
的交互:
- lock:作用于主内存,把变量标识为线程独占状态。
- unlock:作用于主内存,解除独占状态。
- read:作用主内存,把一个变量的值从主内存传输到线程的工作内存。
- load:作用于工作内存,把read操作传过来的变量值放入工作内存的变量副本中。
- use:作用工作内存,把工作内存当中的一个变量值传给执行引擎。
- assign:作用工作内存,把一个从执行引擎接收到的值赋值给工作内存的变量。
- store:作用于工作内存的变量,把工作内存的一个变量的值传送到主内存中。
- write:作用于主内存的变量,把store操作传来的变量的值放入主内存的变量中。
volatile如何保持内存可见性
volatile的特殊规则就是:
- read、load、use动作必须连续出现。
- assign、store、write动作必须连续出现。
所以,使用volatile变量能够保证:
- 每次
读取前
必须先从主内存刷新最新的值。 - 每次
写入后
必须立即同步回主内存当中。
也就是说,volatile关键字修饰的变量看到的随时是自己的最新值。线程1中对变量v的最新修改,对线程2是可见的。
防止指令重排
编译器在生成字节码时,会在指令序列中插入
内存屏障来禁止特定类型的处理器重排序。
内存屏障来禁止特定类型的处理器重排序。
volatile
的底层实现原理是内存屏障,
Memory Barrier
的底层实现原理是内存屏障,
Memory Barrier
对
volatile
变量的写指令后会加入写屏障
volatile
变量的写指令后会加入写屏障
对
volatile
变量的读指令前会加入读屏障
volatile
变量的读指令前会加入读屏障
内存屏障之前的所有写操作都要写入内存;内存屏障之后的读操作都可以获得同步屏障之前的写操作的结果。
参考
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/92818.html