volatile关键字的作用及使用场景

volatile的使用场景 参考:https://www.ibm.com/developerworks/cn/java/j-jtp06197.html 总结 其实换个角度,非常简单能够理解和应用: 一个引用指明了一个内存的地址,地址上有引用反映出来的值。 比如:Integer i = 1 ; 引用 i 指向 一个地址 0x10101 地址 0x10101 上的值为 1 ; 为了线程安全,volatile能修... 阅读详情

volatile关键字是java虚拟机提供的最轻量级的同步机制。在并发的场景下,我们都习惯于使用synchronized锁进行同步,其实,有些简单的场景下,我们也可以使用volatile来代替,但volatile有它本身的使用规则,不能滥用,要结合它自身的特性把它应用于适合的场景下。下面就来简单叙述一下volatile关键字的作用,及其适用场景。

一、volatile的特性

被volatile修饰的变量将会有两个特性,第一是保证此变量对所有的线程的可见性;第二是禁止指令重排。

1、可见性

这里的可见性,指的是一条线程修改了被volatile修饰的变量的值后,新值对于其他线程也是立即得知的。
如下图,当某时刻线程T1对变量V作了B操作,那么线程T2、T3也可以马上感知到V被作了B操作。
在这里插入图片描述
熟悉jvm内存模型的童鞋,应该知道变量(不包括局部变量和方法变量)都是存在于主内存中,而每个线程对此变量的所有操作都必须通过工作内存,工作内存会不断的从主内存读取数据,或往主内存写入数据。在多线程对同一个变量进行操作时,会存在“可见性”问题。而volatile关键字来修饰变量,就是使得线程每次使用变量时都会强制先从主内存刷新到工作内存,每次修改变量时都会强制立刻把工作内存中发生的改变回写到主内存中。这样就实现了“当一个线程对变量操作时,其他线程都可以感知到”这样的说法。
那么,volatile就一定是线程安全了吗?然而并不是,volatile只是增强了可见性,但都是有前提的。对一个变量的操作,其实很多都不是原子操作,比如一个整型全局变量a,a++这样的操作就不是原子操作,它可以拆解成3条指令:

1、从主内存取出变量a的值,load到工作内存中;
2、工作内存中的a值加1;
3、工作内存中新的a值回写到主内存。

由此可见,就算volatile保证了变量的可见性,但在多线程的环境下,依然保证不了线程安全,因为多线程的读取、写入总会存在差异,此时应该使用原子类乃至锁机制方可解决。(以上的例子不是很严谨,因为一条高级语言指令也是由很多条机器指令完成)

2、禁止指令重排

CPU和编译器为了提升程序执行的效率,会按照一定的规则允许进行指令重排。指令重排在单线程是没什么问题的,但如果是多线程的情况下,就有可能产生意想不到的现象。如下程序:

class UnsafeExam {
  int x = 0;
  boolean v = false;
  //volatile boolean v = false;
  public void writer() {
    x = 42;
    v = true;
  }
  public void reader() {
    if (v == true) {
      // 这里 x 会是多少呢?
      System.out.print(x);
    }
  }
}

由以上程序,如果编译器优化的时候,把x = 42和v = true换了个位置,在多线程的环境下,后果是不堪设想的,x的值输出可能是0或42。如果变量v加个volatile修饰,相当于加了个内存屏障,指令重排时不能把后面的指令重排序到内存屏障之前的位置。

二、性能

volatile变量读操作的性能消耗与普通变量差别不大,单是写操作可能会慢一些,因为他需要在本地代码插入许多内存屏障指令来保证处理器不发生乱序执行。不过即便如此,大多数场景volatile关键字的总开销要比锁来的更低。我们在volatile与锁中选择的唯一判断一句仅仅是volatile语义能否满足使用场景的需求。

三、适用场景

由于volatile只能保证可见性,则使用时必须遵守以下原则,否则需要考虑使用原子类乃至锁机制。

  1. 运算结果不依赖变量的当前值,或者能确保只有单一的线程修改变量的值;
  2. 变量不需要与其他状态变量共同参与不变约束。
volatile关键字原理的使用介绍和底层原理解析和使用实例 volatile的定义及作用:可见性、有序性和禁止优化。volatile的底层实现原理:JMM、缓存一致性协议和内存屏障。volatile的使用实例:双重检查锁定和中断机制等。如何解决volatile的原子性问题:使用synchronized和Atomic类。AtomicStampedReference用法和ABA问题解决。一些volatile的最佳实践。使用volatile和锁实现的一个简单线程安全容器。 阅读详情

相关推荐

【C/C++实战篇】volatile的作用是什么? volatile的存储类型、特征修饰、数据类型?volatile三种应用场合

volatile修饰符用于防止编译器优化变量,确保每次访问都从内存读取最新值,适用于中断、多线程和硬件寄存器等易变场景。C语言变量定义包含存储类型(auto/static/register/extern)、特征修饰(如volatile)、数据类型和变量名。volatile可用于中断服务程序、多线程共享标志和硬件寄存器,避免因优化导致错误。但过度使用可能增加代码体积和降低性能。此外,volatile可与const或extern叠加使用,如只读状态寄存器或外部共享变量。合理使用volatile能保证程序

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 2922

Java中的volatile关键字的作用

volatile关键字是Java中一个非常重要的关键字,它可以保证共享变量的可见性和禁止指令重排序,但是无法保证原子性。在多线程编程中,我们应该根据具体情况选择使用volatile关键字或synchronized关键字,以保证程序的正确性和效率。

zhaoliubao1的博客 5466

5-DOF机械臂课程设计(一)之正逆运动学

文章目录基本要求基本概念关节坐标系的建立正运动学求解DH参数表的建立逆运动学求解多解下解的选取源码下载后续 基本要求 ​ 开发上位机程序,要求有良好的界面,能提供关节空间下和笛卡尔坐 标下表示的目标位姿点和中间若干经过点的输入功能,进行轨迹规划, 并控制机械臂沿轨迹运动,最终完成目标抓取的任务。 基本概念 连杆长度 :2个相邻关节轴线之间的距离 连杆扭角 :2个相邻关节轴线之间的角度 连杆偏距 :2个关节坐标系的X轴之间的距离 关节角度 :关节变量 计算时需要加初始角度偏移 关节坐标系的建立 ​ 根据《机

Rosen的博客 5855

由浅入深讲解volatile

volatile volatile 是一个类型修饰符。volatile 的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略 volatile 的特性 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。(实现可见性) 禁止进行指令重排序。(实现有序性) volatile 只能保证对单次读/写的原子性。i++ 这种操作不能保证原子性。关于volatile 原子性可以理解为把对volatile变量的单个读/写,看成是使用同一个锁对这些单

尘泥沉溺的博客 1315

工程制图习题集张大庆课后习题答案解析

所以,我想向大家求助,希望能得到一些学习资料、学习方法和学习经验,帮助我更好地理解和掌握这门课程。在寻找学习资料的过程中,我发现了一款叫做资小料的APP,它里面有很多关于工程制图的学习资料,包括视频教程、习题解答和考试真题等。通过使用资小料,我逐渐掌握了工程制图的基本理论和方法,解决了很多学习中遇到的问题。在这里,我想推荐给和我一样在学习《工程制图习题集》这门课的同学们,希望大家也能从这款APP中受益,共同进步。上传者: 『Consentesdei』蒼迷穀。出版社: 清华大学出版社。

weixin_58833001的博客 925

SAP后台JOB保姆级教程:从SM36创建到SM37监控,手把手教你搞定ABAP程序定时任务

本文详细解析SAP后台JOB从创建到监控的全流程,重点介绍SM36创建和SM37监控的操作步骤与最佳实践。通过真实案例演示如何配置定时任务、处理常见故障及实施企业级管理策略,帮助ABAP开发者高效管理后台程序执行。

weixin_30838873的博客 430

java 关键字 volatile_java volatile关键字作用及使用场景

1. volatile关键字的作用:保证了变量的可见性(visibility)。被volatile关键字修饰的变量,如果值发生了变更,其他线程立马可见,避免出现脏读的现象。如以下代码片段,isShutDown被置为true后,doWork方法仍有执行。如用volatile修饰isShutDown变量,可避免此问题。1 public classVolatileTest3 {2 static ...

weixin_30618305的博客 2778

java 二维码生成及其标签打印

本文主要内容 二维码生成 二维码标签预览及打印 二维码生成 笔者此次的二维码是通过调用第三方接口生成的,具体流程如下: 根据规范要求调用第三方接口,返回二维码下载地址及二维码图片的属性值(图片大小等) 根据返回的值获取二维码下载地址,根据地址下载二维码图片,保存至本地磁盘及记录数据信息 扫描二维码跳转相应地址,显示资产的基本信息 最终生成的二维码如下图所示: 预览并批量打印二维码标签 先...

孙小牟的博客 4941

Java 中 volatile 关键字的作用及使用场景

在 Java 中,volatile关键字是一种轻量级的同步机制,它确保了对变量的读写操作不会被 JVM 优化,且对一个线程写入的值能够及时对其他线程可见。具体来说,volatile可见性:当一个线程修改了某个volatile变量的值,其他线程立即能够看到这个值的最新修改。禁止重排序:编译器和 JVM 不能对volatile变量的读写操作进行指令重排,确保操作顺序不会被改变。特性volatile关键字线程可见性保证线程间对变量的可见性保证线程间的可见性原子性不保证原子性保证原子性性能。

一碗黄焖鸡三碗米饭的博客 1773

运放比较电路分析以及应用

摘要:本文介绍了基于LM321运放的同相输入型单限电压比较器电路。该电路通过运放开环工作模式实现电平判断:当输入信号Vs+>0V时输出+15V高电平,Vs+<0V时输出≈0V低电平。典型应用包括直流电压过零检测、交流信号整形、电池欠压报警和数字信号噪声过滤。电路具有结构简单(仅需1个运放和1个电阻)、成本低的优势,适用于传感器信号处理、波形转换等场景。使用时需注意参考电平调整、输出电平匹配等问题,如需抗噪声可增加正反馈电阻构成施密特触发器。该电路是运放实现简单电平逻辑的经典方案。

qq_37999850的博客 395

VS2019项目使用CGAL6.1配置教程详细步骤

在VS2019项目中使用CGAL详细步骤

插件开发 331

java volatile关键字的作用_java volatile关键字作用及使用场景详解

1. volatile关键字的作用:保证了变量的可见性(visibility)。被volatile关键字修饰的变量,如果值发生了变更,其他线程立马可见,避免出现脏读的现象。如以下代码片段,isShutDown被置为true后,doWork方法仍有执行。如用volatile修饰isShutDown变量,可避免此问题。public class VolatileTest3 {static class W...

weixin_30895873的博客 2545

CPD (Coherent Point Drift) 算法实现点云配准 C++版

作为和icp并列的点集配准算法cpd为什么没有icp火,等我把整个方案跑完才明白。 首先下载cpd https://github.com/gadomski/cpd 包含的fgt https://github.com/gadomski/fgt 下载到win10的解压后 运行cmake来进行编译 这个时候会提醒缺少eigen3 fgt python 这几个都安装排除后 在build文件夹下会生成vs2017的源码,右键全部生成后在 .\cpd-master\build\Debug 下会生成一个cpd.li

uranus1992的博客 3510

volatile关键字的作用-适用场景

volatile在Java并发编程中常用于保持内存可见性和防止指令重排序。内存可见性(Memory Visibility):所有线程都能看到共享内存的最新状态;防止指令重排:在基于偏序关系的Happens-Before内存模型中,指令重排技术大大提高了程序执行效率,但同时也引入了一些问题。 volatile保持内存可见性的特殊规则:read、load、use动作必须连续出现;assign、stor...

sinolover的专栏 843

5、快速入门

点击启动实例按钮,并设计一个business key,每个实例会有一个business key, 业务主键,也相当于一个流程实例唯一key,一般会与一次业务强相关,比如一个订单号 ,此处取为shopping_1;付款程序完成后会流转到物流发货任务,此时java工程的相应订阅会收到任务,并进入断点,且读到到toWhere变量。单击shopping可以进入实时流程图的执行图,此时流程流转到第一个任务,需要业务系统完成此任务,并通知引擎。添加类,分别订阅流程中的加入购物车任务和物流发货任务。

leyoliu的博客 3499

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Java并发编程(二)—volatile关键字的作用及使用场景

volatile在这篇文章多次提及volatile,这是一个非常重要的概念,主要用于多线程编程中,它确保了变量的可见性和禁止指令重排序,但不保证原子性,下面详细解释。

echola_mendes的博客 1403

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

关键字static、const与volatile的作用与使用场景

1. static關鍵字的使用有三種場景: 1) 修饰函数体内的变量(局部变量) :被static修飾的局部變量只執行一次初始化,延長了其生命週期; 2) 修饰函数体外的变量(全局變量) :被staitc修飾的靜態全局變量只能在本文件中被訪問,不能在其他文件中被訪問; 3) 修饰函数:被static修飾的函數只能在本文件中被調用,不能被其他文件所調用。 2. 被const修飾的變量...

一棹春风一叶舟,一纶茧缕一轻钩 1061

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

java volatile关键字作用及使用场景

java volatile关键字作用及使用场景 volatile关键字的作用:保证了变量的可见性(visibility)。被volatile关键字修饰的变量,如果值发生了变更,其他线程立马可见,避免出现脏读的现象。如以下代码片段,isShutDown被置为true后,doWork方法仍有执行。如用volatile修饰isShutDown变量,可避免此问题。 public class VolatileTest3 { static class Work { boolean isShu

qq_40603010的博客 1565

在高并发场景下单例模式中volatile关键字的作用

在高并发场景下单例模式中volatile关键字的作用

技术杠精的博客 1090

volatile 关键字的使用场景和作用。

volatile关键字在这些场景中的作用是确保变量的可见性和一致性,防止编译器对变量的访问进行优化,从而避免因优化而导致的意外行为或错误。

fz2891897770的博客 3825

volatile关键字的作用和应用场景【面试备用】

Volatile Volatile : (意思是 不稳定的)限定一个对象可被外部进程(操作系统、硬件或并发线程等)改变,声明时的语法如下: int volatile nVint; 这个说明 让程序每次读取nVint 真正的值。 volatile int i=10; int a = i; ... // 这里的代码可能回改变i 的值 // 其他代码,并未明确告诉编译器,对 i 进行过操作 int b = i; 在上面 volatile 指出 i 是随时可能发生变化的,每次使用它的时候必须从 i的地

刘小雨的博客 5146

面试题:请解释Java中的volatile关键字的作用,并举例说明在多线程环境下使用volatile关键字的场景以及它的局限性

volatile关键字在Java多线程编程中有一定的作用,主要用于保证变量的可见性和禁止指令重排序。它适用于一些简单的场景,如状态标志和单次赋值的共享变量,但在处理复合操作的原子性等方面存在局限性,在复杂的并发场景下需要结合其他并发工具来确保程序的正确性。

胡子发芽的博客 561

volatile关键字的作用及应用场景

C语言中的volatile关键字有何作用? 编译器的优化方式有:将内存变量缓存到寄存器,由于访问寄存器要比访问内存单元快的多。 有时编译器对代码会自动进行优化,该关键字就是让编译器不要进行编译优化。volatile意思是“易变的”“直接存取原始内存地址”。(防止变量改变后被编译器优化一直只读寄存器第一次的值,不变了) 常用地点: 中断服务程序中修改的供其它程序检测的变量,需要加volatile;(编译器判断主函数里没有改变该变量,就可能把他优化了,那就拿不到改变后的变量值了) 多任务环境下各任务间共享的标

weixin_42155498的博客 1339

INetwork 接口和之前的 AsyncTcpServer 上下文,我将详细讲解 C++ 中的 volatile 关键字,分析其作用、用法,以及与 const 关键字的区别和结合使用场景

本文详细讲解了C++中volatile关键字的作用、用法及其与const的区别。volatile主要用于防止编译器优化,适用于多线程共享变量、硬件寄存器访问等场景。文章结合INetwork接口和AsyncTcpServer,分析了GetError和Initialize方法中volatile的适用性,指出在多线程环境下std::atomic比volatile更合适。提供了const volatile组合使用示例,并对比了volatile与const的特性差异。最后给出了Visual Studio 2022的配

专注于前沿技术的探索与实践,热衷于从代码逻辑、架构设计到行业应用等多维度深挖技术本质。期待在技术之路上与你共同成长~ 687
上一篇: windows修改了my.ini后无法启动mysql
下一篇: 记一次filebeat与logstash配合使用遇到的坑
H阿布
博客等级 码龄12年 24粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值