Hi! 我是小小,今天是本周的第六篇,主要内容是关于 volatile 关键字。

前言

volatile 关键字主要是用于指令重排序,常常用于保证内存的可见性和防止指令重排序。

保证内存可见性

内存可见性是指所有线程都能看到共享内存的最新的状态。例如,在多线程环境中,加上 volatile 关键字以后,每个线程的内存会强制刷新到主内存中,实现每个线程都保证其关键字内存是最新的。

从一个例子说起

举一个失效的代码

public class MutableInteger {private int value;public int get(){return value;}public void set(int value){this.value = 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文件进行打乱。

  2. 在硬件层面,CPU会把接受到的程序,和一批指令按照一定的规则进行从排序,同样是缓存和CPU速度的问题。

被 volatile 关键字修饰的变量,会在之前添加一个 lock 汇编指令,用于强制防止指令从排序。

如何禁止

通过内存屏障实现,内存屏障分为 写屏障,读屏障,读写屏障。

  1. 编译器,在编译器层面,在编译器层面会对指令进行从排序,添加了 volatile 关键字以后会对指令进行从排序,这样可以显示的告知编译器应该避免生成的代码违背预期。

  2. 机器相关:在多核机器下,由于程序是多线程运行的,操作系统,直接调用 CPU 所实现的内存屏障,在硬件层面,实现其原子性操作。

关于作者

我是小小,一个生于二线,活在一线城市的程序猿,我是小小,我们下期再见。

小明菜市场

推荐阅读

● 3W | 跟着小小学会这些 Java 工程师面试题,月薪至少 3 W

● 十年 | 在Java开发做了10年后,才学会此绝招,用于颠覆Java应用

● DJL | DJL 如何正确打开 [ 深度学习 ]

● 警惕 | 警惕,mybatis的size()方法竟然有坑!

● 详解 | Spring Boot 最核心的 3 个注解详解

给我个好看再走好吗?

没想到 | 万万没想到 Java 中最重要的关键字竟然是这个相关推荐

  1. 万万没想到 Java 中最重要的关键字竟然是这个!

    作者 | 小明菜市场 来源 | 小明菜市场(ID:fileGeek) 头图 |  CSDN 下载自东方IC volatile 关键字主要是用于指令重排序,常常用于保证内存的可见性和防止指令重排序. 保 ...

  2. java底层原理书籍_阿里面试题:Java中this和super关键字的底层实现原理

    知道的越多,不知道的就越多,业余的像一棵小草! 编辑:业余草 来源:https://www.xttblog.com/?p=5028 B 站:业余草 最近一个粉丝加我说,接到了阿里的面试,问问我阿里会面 ...

  3. Java中的两个关键字——super、this

    Java中的两个关键字--super.this 神话丿小王子的博客主页 一.super super 是java中方的一个关键字,用它可以引用父类中的成员: super可用于访问父类中定义的属性 sup ...

  4. Java中的50个关键字

    2019独角兽企业重金招聘Python工程师标准>>> Java中的50个关键字 关键字也称为保留字,是指java语言中规定了特定含义的标示符.对于保留字,用户只能按照系统规定的方式 ...

  5. [转载] Java中的50个关键字

    参考链接: Java平台如何独立 Java中的50个关键字 关键字也称为保留字,是指java语言中规定了特定含义的标示符.对于保留字,用户只能按照系统规定的方式使用,不能自行定义.Java中有50个常 ...

  6. java中定义类的关键字是_java中定义类的关键字是什么?

    java中定义类的关键字是:"class".在Java中定义一个类,需要使用"class"关键字.一个自定义的类名和一对表示程序体的大括号. 类是 Java 中 ...

  7. java下面哪些定义正确,请问,以下哪些是java中定义的合法关键字?请选择所有正确答案:...

    请问,以下哪些是java中定义的合法关键字?请选择所有正确答案: 答:interface sizeof volatile "凡是亲眼所见的都是对客观事实的真实反映",这个命题 答: ...

  8. 一语点破 Java 中的静态 static 关键字

    来源 | blog.csdn.net/ju_362204801/article/details/90738966 思考:大家有没有想过一个问题,静态它为什么叫静态?因为书上或者别的文章里这么写的都这么 ...

  9. java中的标识符和关键字_浅谈java中的标识符、修饰符和关键字

    合法标识符 Java语言中,对于变量,常量,函数,语句块均有名字,我们统统称之为Java标识符.标识符是用来给类.对象.方法.变量.接口和自定义数据类型命名的. 组成:Java标识符由数字,字母和下划 ...

最新文章

  1. js和java中URI的编码和解码
  2. tl-wn821n无线网卡驱动 linux,tl-wn821n win10驱动
  3. uni-app实现微信小程序本地图片转为base64
  4. Netty学习总结(6)——Netty使用注意事项
  5. servlet的应用------request对象和bean实体的反射关系
  6. 算不算被虚度的这几年
  7. 在Azure ML中使用Logistic回归预测客户的贷款资格
  8. Python多任务之多进程开发
  9. 计算机怎么改鼠标标志,图文帮你如何自定义电脑鼠标指针的图标
  10. mind map 思维导图
  11. 推荐一款3D插件可以用纯html+css打造3D效果
  12. 2021-06-07 QQ注册
  13. Android 11.0 任务栏中清除掉播放器的进程,状态栏仍有音乐播放器状态问题的解决
  14. 老猪带你玩转自定义控件三——sai大神带我实现ios 8 时间滚轮控件
  15. PPT播放显示备注技巧
  16. firefox地址栏搜索
  17. Hashtable的用法
  18. 从知识女性转变为家庭妇女
  19. 如何保证游戏长盛不衰
  20. IE8展示SVG图像问题处理

热门文章

  1. 常见的 HTTP 状态代码及原因
  2. 安装vsphere update manager及注意事项
  3. 判断用户是否已经登录
  4. 操作系统(10)-虚拟内存
  5. 思维导图系列之Java多线程知识梳理
  6. Merge Into 语句代替Insert/Update在Oracle中的应用实战
  7. 《集体智慧编程》代码勘误:第六章
  8. 荣耀9“致敬”小米6?这是今年手机界最大的笑话!
  9. postgresql常用函数及操作符及类型转换
  10. 【Unity】8.5 扩展编辑器