volatile关键字简介
volatile的作用
- 保证变量在多线程中的可见性
- 保证指令的有序性(禁止指令重排)
保证变量在多线程中的可见性
主存中有一个变量a, 它被volatile关键字所修饰, 并且它的值是0
T1和T2线程读取了变量a, 此时它们的线程的本地内存(CPU寄存器或高速缓存)中的值都是0
如果T1修改了变量a的值为1, 由于被a变量被volatile所修饰, 那么T1修改之后的a就会被刷新到主存(写屏障), 并且执行T2线程的CPU对a变量的缓存行会失效(读屏障), 强制从主存中获取值, 到达了多线程中变量的可见性的目的
通过内存屏障保证变量在多线程中的可见性, 如果字段被volatile修饰:
- 读屏障: 在读指令前插入读屏障,可以让高速缓存中的数据失效,重新从主内存加载数据
- 写屏障: 在写指令之后插入写屏障,能让写入缓存的最新数据写回到主内存
保证指令的有序性(禁止指令重排)
指令重排的意义
JVM能够根据CPU的特性(CPU的多级缓存系统、多核处理器等)适当的重新排序机器指令,使机器指令更符合CPU的执行特点,最大限度的发挥CPU的性能,提高效率。
单线程情况下, 指令重排没问题, 但是多线程环境下, 指令重排可能造成程序的执行结果并不是我们所期待的, 比如单例模式的DCL写法对DCL单例模式的思考
volatile通过两点保证指令有序性
happens-before
happens-before原则(定义一些禁止编译优化的场景,保证并发编程的正确性), 下图来源于: 来源《Java并发编程实践》

内存屏障
编译器在生成字节码时, 会在指令序列中插入内存屏障,会多出一个 lock 前缀指令
内存屏障是一组处理器指令,解决禁止指令重排序和内存可见性的问题,保证指令重排序后与之前的输出结果一 样,使性能得到优化, 处理器在进行重排序时是会考虑指令之间的数据依赖性。
先于这个内存屏障的指令必须先执行,后于这个内存屏障 的指令必须后执行
使用 volatile 的经典场景
- 双重校验锁 DCL(double checked locking)
- ConcurrentHashMap的哈希数组Node[]
- 原子类例如AtomicInteger的value属性
- 多个线程操作同一块内存的同一个变量(保证有序性和内存可见性,有序性和可见性同等重要,都不能忽略)
volatile关键字简介的更多相关文章
- java 轻量级同步volatile关键字简介与可见性有序性与synchronized区别 多线程中篇(十二)
概念 JMM规范解决了线程安全的问题,主要三个方面:原子性.可见性.有序性,借助于synchronized关键字体现,可以有效地保障线程安全(前提是你正确运用) 之前说过,这三个特性并不一定需要全部同 ...
- C语言中的volatile关键字简介
C语言中的volatile关键字简介: (1)含义: volatile关键字的意思是可能会被外来的意想不到的改变.它的作用是:优化器在使用该关键字定义的变量时,直接从内存中读取原始的数 ...
- volatile关键字与线程间通信
>>Java内存模型 现在计算机普遍使用多处理器进行运算,并且为了解决计算机存储设备和处理器的运算速度之间巨大的差距,引入了高速缓存作为缓冲,缓存虽然能极大的提高性能,但是随之带来的缓存一 ...
- volatile关键字学习
volatile关键字在实际工作中我用的比较少,可能因为我并不是造轮子的.但是用的少不是你不掌握的借口,还是要创造场景去使用这个关键字,本文将会提供丰富的demo. volatile 发音:英[ˈvɒ ...
- Java多线程学习(三)volatile关键字
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79680693 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- Java并发之(1):volatile关键字(TIJ21-21.3.3 21.3.4)
Java并发Java服务器端编程的一项必备技能. ** 1 简介 volatile是java中的一个保留关键字,它在英语中的含义是易变的,不稳定的.volatile像final.static等其 ...
- 1.volatile关键字 内存可见性
Java JUC 简介 在 Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括 ...
- 【C# 线程】 volatile 关键字和Volatile类、Thread.VolatileRead|Thread.VolatileWrite 详细 完整
overview 同步基元分为用户模式和内核模式 用户模式:Iterlocked.Exchange(互锁).SpinLocked(自旋锁).易变构造(volatile关键字.volatile类.Thr ...
- Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...
- volatile关键字 学习记录2
public class VolatileTest2 implements Runnable{ volatile int resource = 0; public static void main(S ...
随机推荐
- HarmonyOS NEXT开发实战教程-记账app
今天分享的实战教程是一款记账app,最近分享的项目都是纯页面,没有服务端,没有数据接口,因为鸿蒙开发主要就是写页面,都是前端嘛.如果有友友想要完整的项目可以找幽蓝君定制,想学服务端开发的话幽蓝君也可以 ...
- RPC实战与核心原理之网络通信
架构设计:涉及一个灵活的RPC框架 回顾 RPC的通信原理及RPC中各个功能组件的作用 RPC就是把拦截到的方法参数,转成可以在网络中传输的二进制,并保证服务提供方能正确还原出语义,最终实现想调用本地 ...
- #React中类组件中关于回调函数的一个问题
在ES6中,类中定义的方法,是放在原型对象的,供实例对象引用. //创建一个Person类 class Person { constructor(name,age) { this.name = nam ...
- post 报头注入
1.user-agent 注入: 使用情况:万能密码无法绕过安全验证,用户名无法注入,通过查看源代码分析执行的动作. bp抓包修改user_agent的数据如下 User-Agent: ' or ud ...
- 【附源码】C语言的学生管理系统完整实现方案
以下是一个基于C语言的学生管理系统完整实现方案,结合了结构体.链表.文件存储.菜单驱动等核心技术,参考了多个开源项目与课程设计案例. 系统支持管理员/学生双角色权限.数据持久化存储及完整增删改查功能, ...
- java的随机数Random
测试1 1 package com.lv.study.pm.second; 2 3 public class TestMath { 4 5 public static void main(String ...
- tomcat为什么假死了.md
现象 我们生产最近有个服务偶尔会挂掉,接口报错"connection reset by peer",上服务器curl也是同样报错,意思连接被server拒绝了. 通过dump以及日 ...
- SAP发布简易REST 二:API平台之接口配置
API接口平台设计:(全JSON格式) 做ABAP的都知道,一般接口的处理都是封装个函数来单独处理.那么这些函数能不能做成配置呢?又以什么形式的参数来传入传出呢? ps:到目前为止,只是有点想法,所以 ...
- 用Java获取本机IP或者请求用户的真正IP地址
一.在Web请求中获取请求用户的IP地址 public static String getUserRealIP(HttpServletRequest request) throws UnknownHo ...
- 直播预告丨《Flink提交流程&如何debug和跟踪流程(on yarn)》
4月20日晚19点30分,袋鼠云数栈技术研发团队开发工程师--莫问,将会为大家直播分享<Flink提交流程&如何debug和跟踪流程(on yarn)>. 课程内容主要包括以下三点 ...