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 ...
随机推荐
- Superset 1.0.1发布——稳定版本
Apache Superset最近发布了1.0.1版本,这也是1.0版本后的有一个重大的版本,Superset也会在以后有更多的改进.那么让我们来看一下最新的新功能吧. 用户体验 通过更简单,更直观的 ...
- OpenStack Train版-11.安装horizon服务(计算节点)
OpenStack仪表板Dashboard服务的项目名称是Horizon,它所需的唯一服务是身份服务keystone,开发语言是python的web框架Django. 安装Train版本的Horizo ...
- DDL 数据定义语言
目录 创建数据库(CREATE) 删除数据库(DROP) 修改数据库(ALTER) 创建数据表(CREATE) 数据表的数据属性 数据类型属性(Type) 其他属性(Null,Key,Default, ...
- QXDM和QCAT软件使用指南
一.传送门 链接:https://pan.baidu.com/s/1i55YXnf 密码:v6nw 二.QXDM,QPST和QCAT的简单说明 QXDM,QPST和QCAT是Qualcomm高通公司针 ...
- Leetcode(213)-打家劫舍II
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金.这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的.同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在 ...
- C、C++语言中参数的压栈顺序
要回答这个问题,就不得不谈一谈printf()函数,printf函数的原型是:printf(const char* format,-) 没错,它是一个不定参函数,那么我们在实际使用中是怎么样知道它的参 ...
- MAC地址分类
网卡MAC地址作为互联网设备在以太网中身份的唯一标识在以太网通讯中的作用比IP地址还要重要,MAC地址分成两部分,前24位是组织唯一标识符(OUI, Organizationally unique i ...
- Watch the Wifi: Visually Stunning Look at the Digital World Invading Cities (video)
http://singularityhub.com/2011/04/01/watch-the-wifi-visually-stunning-look-at-the-digital-world-inva ...
- Android Activity 与 WebView 页面线程不一致 bug
Android Activity 与 WebView 页面线程不一致 bug refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
- website URL & UTM
website URL & UTM UTM user track message utm_source https://zhuanlan.zhihu.com/p/143473571?utm_s ...