Java volatile关键字详解

volatile是java中的一个关键字,用于修饰变量。被此关键修饰的变量可以禁止对此变量操作的指令进行重排,还有保持内存的可见性。

简言之它的作用就是:

  1. 禁止指令重排
  2. 保持内存的可见性

禁止指令重排

CPU在执行代码时,为了提高执行效率,有时会将代码乱序执行。但是乱序也不是随随便便的乱序,而是在一定规则下,对指令进行重排然后执行。指令重排在单线程下没有什么问题,但是在多线程环境下容易造成并发安全问题。

保持内存的可见性

何谓之内存的可见性,其实笔者在Java线程安全问题一文中对此问题进行过阐述。线程是一种资源,线程在执行代码时有自己的工作内存(线程执行的堆栈)。一般来说,一些共享变量存在于堆内存中,线程对于共享变量的操作实际上对自己工作内存中共享变量的副本进行操作,线程并不会直接操作堆内存的中的共享变量。

这里我们可以通过字节码进行验证,首先我们的java源代码是对变量a进行一个自增操作 => a++,而其对应的字节码为:

getstatic #2
iconst_1
iadd
putstatic #2
return

从字节码层面可以体现出工作内存与主存。但是,Java内存可见性的控制并不是在字节码层面,而是在JVM层面。即使你对变量a使用volatile修饰,那么编译之后的字节码也没有变化。

JVM定义了对于内存的8种操作:

这些操作是JVM层面的操作,在Java源代码中并不能感受到。线程在所操作的共享变量,其实是存在于自己线程栈中的变量副本。在多线程并发的情况下,如果有其他线程修改了主存中的值,那么其他线程无法感知这种修改。因为线程在通过READ-LOAD操作拷贝完副本之后,之后线程对于数据的操作都是对于副本进行的。这也就是内存可见性的问题的来源,简言之就是线程之间无法感知对于主存共享变量的修改。

volatile关键字就是解决了这样的问题,使得线程对于主存具有一定的可见性。其解决方案是对于volatile标注的变量,每次在使用之前都要重新从主存中加载,同时每次对于变量完成修改后,要及时的将变量写回主存。

通过这样的操作,每个线程就能感知到内存中变量的变化,并及时更新自己副本的值。不过需要注意的是,volatile关键字并不能保障并发的安全性。尽管每次在使用之前都会更新值,但是这并没有解决变量访问的有序性。所以在高并发场景下依然会出现问题。

Java volatile关键字详解的更多相关文章

  1. Java Volatile 关键字详解

    原文链接:https://www.cnblogs.com/zhengbin/p/5654805.html 一.基本概念 先补充一下概念:Java 内存模型中的可见性.原子性和有序性. 可见性: 可见性 ...

  2. Java synchronized 关键字详解

    Java synchronized 关键字详解 前置技能点 进程和线程的概念 线程创建方式 线程的状态状态转换 线程安全的概念 synchronized 关键字的几种用法 修饰非静态成员方法 sync ...

  3. Java之先行发生原则与volatile关键字详解

    volatile关键字可以说是Java虚拟机提供的最轻量级的同步机制,但是它并不容易完全被正确.完整地理解,以至于许多程序员都习惯不去使用它,遇到需要处理多线程数据竞争问题的时候一律使用synchro ...

  4. Java并发编程:JMM (Java内存模型) 以及与volatile关键字详解

    目录 计算机系统的一致性 Java内存模型 内存模型的3个重要特征 原子性 可见性 有序性 指令重排序 volatile关键字 保证可见性和防止指令重排 不能保证原子性 计算机系统的一致性 在现代计算 ...

  5. Java多线程-----volatile关键字详解

       volatile原理     Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程.当把变量声明为volatile类型后, 编译器与运行时都会注意 ...

  6. Java中Volatile关键字详解 (转自郑州的文武)

    java中volatile关键字的含义:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 一.基本概念 先补充一下概念:J ...

  7. jvm运行机制和volatile关键字详解

    参考https://www.cnblogs.com/dolphin0520/p/3920373.html JVM启动流程 1.java虚拟机启动的命令是通过java +xxx(类名,这个类中要有mai ...

  8. volatile关键字详解

    本文系转载,原文链接:http://www.cnblogs.com/Chase/archive/2010/07/05/1771700.html,如有侵权,请联系我:534624117@qq.com 引 ...

  9. C/C++中volatile关键字详解 (转)

    1. 为什么用volatile? C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier.这是 BS 在 "The ...

随机推荐

  1. echart关系图平分节点删除时自动平衡问题

    项目场景: 项目场景:Echarts关系图中(不是力图)一个节点x,y是固定的,为了同一列能居中显示,规定:当前列有奇数个元素新节点往下放,有偶数个节点时新节点往上放. 问题描述: 删除中间节点会有空 ...

  2. codeforces 5C

    C. Longest Regular Bracket Sequence time limit per test 2 seconds memory limit per test 256 megabyte ...

  3. 计算机网络基础篇-ppp协议

    所谓的PPP协议是点对点协议,是目前使用最广泛的数据链路层的协议.大部分用户使用电话线拨号入网的,从用户计算机到ISP的链路所使用的数据链路层协议就是PPP协议. 首先介绍下拨号入网的过程.因特网服务 ...

  4. 『数据结构与算法』二叉查找树(BST)

    微信搜索:码农StayUp 主页地址:https://gozhuyinglong.github.io 源码分享:https://github.com/gozhuyinglong/blog-demos ...

  5. Linux Bash Script loop

    Linux Bash Script loop shell 编程之流程控制 for 循环.while 循环和 until 循环 for var in item1 item2 ... itemN do c ...

  6. Vue Cheat Sheet & Nuxt.js Cheat Sheet

    Vue Cheat Sheet & Nuxt.js Cheat Sheet Vue Cheat Sheet https://www.vuemastery.com/pdf/Vue-Essenti ...

  7. code screenshot beautify plugin & 代码截图美化插件

    code screenshot beautify plugin & 代码截图美化插件 代码截图美化 codesnap 微信分享代码截图 https://github.com/kufii/Cod ...

  8. iPhone 12 导入通讯录排序 Bug

    iPhone 12 导入通讯录排序 Bug iOS iOS 通讯录排序问题 Huawei OK solution iOS 切换中英文,修复排序通讯录 bug Awesome iOS Contacts ...

  9. Vue Learning Paths

    Vue Learning Paths Vue Expert refs https://vueschool.io/articles/vuejs-tutorials/exciting-new-featur ...

  10. CSS3 & Flex Layout All In One

    CSS3 & Flex Layout All In One demos https://www.cnblogs.com/xgqfrms/p/10769302.html .flex-contai ...