按关键词阅读:
文章插图
作者 | 小明菜市场
来源 | 小明菜市场(ID:fileGeek)
头图 | CSDN 下载自东方IC
volatile 关键字主要是用于指令重排序 , 常常用于保证内存的可见性和防止指令重排序 。
文章插图
保证内存可见性内存可见性是指所有线程都能看到共享内存的最新的状态 。 例如 , 在多线程环境中 , 加上 volatile 关键字以后 , 每个线程的内存会强制刷新到主内存中 , 实现每个线程都保证其关键字内存是最新的 。
文章插图
从一个例子说起举一个失效的代码
public class MutableInteger {
private int value;
public int get{
return value;
}
public void set(int value){
this.value = http://kandian.youth.cn/index/value;
}
}
这份代码 , 在多线程环境下 , 是正常运行的 , 但是在非多线程环境下属于不正常运行的 , 因为 get 和 set 方法没有添加同步锁 , 如果线程一调用set方法 , 那么正在调用的get方法的线程二 , 可能会看到前值 , 也可能会看到后值 。
解决办法相当的简单 , 直接加上 volatile 关键字 。
private volatile int value;
在上方代码中 , 加上 volatile 关键字以后 , 所有副线程的关键字的内存 , 会强制刷新到主线程中 , 实现每个线程中的变量关键字都能实时的获取到最新值 。 相当于给 get 和 set 方法加锁 。
文章插图
关于 volatile 关键字Java变量的读写主要分为以下几个关键字进行变量的读写 。 lock 把线程标识为独占状态 。 unlock 解除独占状态 read 从主内存传输到工作内存 load 装载进入工作内存 use 把工作内存的值传递给执行引擎 assign 回传工作内存的值 store 把工作内存的值回传给主内存 write 把 store 操作的值回传给主内存中
通过 read load use 三个关键字连续出现 , 以及 , assign , store , write 这三个关键字连续出现 , 保证原子性 。 其控制如下图所示
文章插图
注意:volatile 关键字是一种非锁机制 , 这种机制可以避免锁引起的上下文的切换
文章插图
禁止指令重排序1、什么是指令重排序
- 在虚拟机层面 , 为了尽可能的减少内存操作速度远远慢于CPU运行速度带来的CPU空置的问题 , 虚拟机会按照一定的规则把编译后的class文件进行打乱 。
- 在硬件层面 , CPU会把接受到的程序 , 和一批指令按照一定的规则进行从排序 , 同样是缓存和CPU速度的问题 。
2、如何禁止通过内存屏障实现 , 内存屏障分为 写屏障 , 读屏障 , 读写屏障 。
- 编译器 , 在编译器层面 , 在编译器层面会对指令进行从排序 , 添加了 volatile 关键字以后会对指令进行从排序 , 这样可以显示的告知编译器应该避免生成的代码违背预期 。
- 机器相关:在多核机器下 , 由于程序是多线程运行的 , 操作系统 , 直接调用 CPU 所实现的内存屏障 , 在硬件层面 , 实现其原子性操作 。
文章插图
【万万没想到 Java 中最重要的关键字竟然是这个】点分享
文章插图
文章插图
稿源:(未知)
【傻大方】网址:http://www.shadafang.com/c/111T3164H020.html
标题:万万没想到 Java 中最重要的关键字竟然是这个