Java volatile关键字详解
Java volatile关键字详解
volatile是java中的一个关键字,用于修饰变量。被此关键修饰的变量可以禁止对此变量操作的指令进行重排,还有保持内存的可见性。
简言之它的作用就是:
- 禁止指令重排
- 保持内存的可见性
禁止指令重排
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关键字详解的更多相关文章
- Java Volatile 关键字详解
原文链接:https://www.cnblogs.com/zhengbin/p/5654805.html 一.基本概念 先补充一下概念:Java 内存模型中的可见性.原子性和有序性. 可见性: 可见性 ...
- Java synchronized 关键字详解
Java synchronized 关键字详解 前置技能点 进程和线程的概念 线程创建方式 线程的状态状态转换 线程安全的概念 synchronized 关键字的几种用法 修饰非静态成员方法 sync ...
- Java之先行发生原则与volatile关键字详解
volatile关键字可以说是Java虚拟机提供的最轻量级的同步机制,但是它并不容易完全被正确.完整地理解,以至于许多程序员都习惯不去使用它,遇到需要处理多线程数据竞争问题的时候一律使用synchro ...
- Java并发编程:JMM (Java内存模型) 以及与volatile关键字详解
目录 计算机系统的一致性 Java内存模型 内存模型的3个重要特征 原子性 可见性 有序性 指令重排序 volatile关键字 保证可见性和防止指令重排 不能保证原子性 计算机系统的一致性 在现代计算 ...
- Java多线程-----volatile关键字详解
volatile原理 Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程.当把变量声明为volatile类型后, 编译器与运行时都会注意 ...
- Java中Volatile关键字详解 (转自郑州的文武)
java中volatile关键字的含义:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 一.基本概念 先补充一下概念:J ...
- jvm运行机制和volatile关键字详解
参考https://www.cnblogs.com/dolphin0520/p/3920373.html JVM启动流程 1.java虚拟机启动的命令是通过java +xxx(类名,这个类中要有mai ...
- volatile关键字详解
本文系转载,原文链接:http://www.cnblogs.com/Chase/archive/2010/07/05/1771700.html,如有侵权,请联系我:534624117@qq.com 引 ...
- C/C++中volatile关键字详解 (转)
1. 为什么用volatile? C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier.这是 BS 在 "The ...
随机推荐
- kubernetes实战-配置中心(一)configmap资源
在我们的环境中测试使用configmap资源,需要先对我们的环境进行一些准备,首先将dubbo服务调整为0个pod ,然后把zookeeper进行拆分: 拆分zk环境,模拟测试环境跟生产环境: 停止z ...
- javascript和XML
一,浏览器对XML DOM的支持1,DOM2级核心 var xmldom = document.implementation.createDocument("","roo ...
- js sort map by key
js sort map by key Map map to array // Array.from() Object let obj = {}; for(let key of Object.keys( ...
- Flutter for Desktop
Flutter for Desktop https://flutter.dev/desktop https://github.com/flutter/flutter/wiki/Desktop-shel ...
- YFI币之后,BGV能否主宰DeFi 沉浮?
回望今年,币圈风起云涌,比特币.YFI.BGV等一众数字货币共同打造了火热的币圈景象,在短短的时间里可以说是又形成了新的生态,业内对于BGV等新币种的认可度也达到了新高.2020已经接近尾声,放眼20 ...
- 开源OA办公系统的“应用市场”,能够为协同办公开拓什么样的“前路”?
在我们的日常生活中,应用市场这个词,总是与智能手机划上等号,不管使用的是iPhone还是安卓,总会接触到手机上的APP应用市场,我们可以在应用市场中,选择自己所需要的APP应用软件,下载使用后,可以让 ...
- EF获取数据库表名和列名
EF获取数据库表名和列名 新建 模板 小书匠 /// <summary> /// 通过当前DBContext上下文获取对应数据库中所有得表 /// </summary> ...
- this指针、引用、顶层和底层const关系
1.首先顶层const和底层const是围绕指针*p的说法.底层:const int *p,const不是修饰指针p,指针所指的值不能改变:顶层:int *const p,const修饰指针p,指针本 ...
- Bootstrap下拉菜单、按钮式下拉菜单
1. 概述 下拉菜单使用频率也是比较高的,比较常见的使用场景是在导航菜单栏,某个主菜单含有下拉的子菜单. Bootstrap为下拉菜单提供了两种实现方式,即普通的下拉菜单还有按钮式的下拉菜单.我们先看 ...
- es6 快速入门 系列 —— 变量声明:let和const
其他章节请看: es6 快速入门 系列 变量声明:let和const 试图解决的问题 经典的 var 声明让人迷惑 function demo1(v){ if(v){ var color='red' ...