volatile

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

volatile:

JVM 提供的轻量级的同步机制。保证了并发编程的可见性、有序性
不保证原子性

1、可见性:

定义:

有一个线程将主内存中的变量值做了修改,其他线程都将马上收到通知,立即获得最新值

  • 写线程:JMM会把该线程对应的本地工作内存中的共享变量值刷新到主内存。
  • 读线程:JMM会把该线程对应的本地工作内存置为无效,线程将到主内存中重新读取共享变量。
原理:

专业术语:

  • 内存屏障(memory barriers):一组处理器指令,用于实现对内存操作的顺序限制。
  • 缓存行(cache line):CPU高速缓存中可以分配的最小存储单位。处理器填写缓存行时会加载整个缓存行。
  • 借助了CPU的lock指令,lock指令在多核处理器下,
    1. 可以将当前处理器的缓存行的数据写回到系统内存,
    2. 同时使其他CPU里缓存了该内存地址的数据置为无效
案例演示:
public class VolatileDemo {
    volatile int number = 0;
    public static void main(String[] args) {
        VolatileDemo test1 = new VolatileDemo();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"开始执行时,number = "+test1.number);
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                test1.add();//暂停3秒后,修改number的值。
                System.out.println(Thread.currentThread().getName()+"执行add()方法之后,number = "+test1.number);
            }
        },"t1").start();
        while (test1.number == 0){}
        System.out.println(Thread.currentThread().getName()+"程序结束!");
    }
    public  void add(){
            this.number = 10;
    }
}
  • 不加volatile,因为不在同一个线程内,一直陷入死循环
  • 加了volatile,此变量信息一旦改变,会通知其他线程获取新值
    • 将会把该线程对应的本地工作内存中的共享变量值刷新到主内存。
    • 会把读线程对应的本地工作内存置为无效,线程将到主内存中重新读取共享变量。

2、有序性:

防止指令重排

指令重排序:编译器和处理器重排序,

JMM会分别限制这两种指令重排序。(通过内存屏障)

介绍:

执行程序时,为了提高计算性能,编译器和处理器常常会对指令进行重排序,一般分为如下3种:

  • 源代码 ——> 编译器优化的重排 ——> 指令并行的重排 ——>内存系统的重排 ——> 最终执行的指令
  • 单线程环境下,可以确保程序最终执行结果和代码顺序执行结果的一致性(单线程环境下不用关注指令重排,因为是否重排都不会出错)。处理器在进行重排序时,必须要考虑指令之间的数据依赖性。
  • 多线程环境中,线程交替执行。由于编译器优化重排的存在,两个线程中使用的变量能否保证一致性是无法确定的,结果也就无法预测。
  • 用volatile关键字修饰的变量,可以禁止指令重排序,从而避免多线程环境下,程序出现乱序执行的现象。
解决方案-内存屏障:

volatile写操作:前后均加内存屏障

volatile读操作:在后面插入两个内存屏障。

  • 在每个volatile写操作的前面插入一个StoreStore屏障,防止写volatile与后面的写操作重排序。
  • 在每个volatile写操作的后面插入一个StoreLoad屏障,防止写volatile与后面的读操作重排序。
  • 在每个volatile读操作的后面插入一个LoadLoad屏障,防止读volatile与后面的读操作重排序。
  • 在每个volatile读操作的后面插入一个LoadStore屏障,防止读volatile与后面的写操作重排序。
内存屏障解释说明
StoreStore屏障禁止上面的普通写和下面的volatile 写重排序。
StoreLoad屏障防止上面的volatile 写与下面可能存在的volatile 读/写重排序
LoadLoad屏障禁止下面所有的普通读操作和上面的volatile读重排序。
LoadStore屏障禁止下面所有的普通写操作和上面的volatile读重排

3、不保证原子性:

原子性定义:

要么不做,要么全做

  • 当某个线程正在执行某件事情的过程中,是不允许被外来线程打断的。
  • volatile不能保证原子性,即执行过程中是可以被其他线程打断甚至是加塞的。
解决方案:
  1. 操作方法加synchronized,悲观锁机制,重量级
  2. 具体操作属性变成原子类,如AtomicInteger,乐观锁机制,值刷新的时候加锁
YooAsset 学习 YooAssets使用教程 阅读详情

相关推荐

高德地图+Three.js实战:手把手教你打造数字农场3D可视化大屏(附完整源码)

本文详细介绍了如何利用高德地图JS API与Three.js技术栈,构建一个功能强大的数字农场3D可视化大屏。文章从技术选型、架构设计出发,深入讲解了坐标对齐、图层管理、性能优化等核心工程实践,并提供了完整的模块化代码示例,旨在为智慧农业及类似场景的3D地理可视化项目提供一套可复用的解决方案。

k8s6orchestrator的博客 890

掉了两根头发,可算是把volatile整明白了

为什么只能保证可见性?又是怎么实现禁用指令重排?哇,原来这么简单

成都彭于晏 2万+

jmeter5.4.1 使用案例

jmeter主要用于接口压力测试,模拟海量请求并发访问接口 1.下载jmeter https://jmeter.apache.org/download_jmeter.cgi 2.启动jemter 双击即可 3.配置jmeter 1.先更改语言 2.创建线程组 配置线程执行规划 3.创建http请求默认值 4.创建http请求 5.创建http信息头管理器 指定 Content-Type:application/json 6.创建响应断言 7.创建察看结果数 直接点击 执行 按.

SpringHASh的博客 1222

volatile详解

一. volatile的内存语义 当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值立即刷新回主内中 当读一个volatile变量时,JMM会把该线程对应的本地内存设置为无效,直接从主内存中读取共享变量 所以volatile的写内存语义是直接刷新到主内存中,读的内存语义是直接从主内存中读取 二.volatile变量的读写过程 Java内存模型中定义的8种工作内存与主内存之间的原子操作: read(读取) -> l...

枫陵的博客 1万+

2022年全球市场微波等离子体CVD反应器总体规模、主要生产商、主要地区、产品和应用细分研究报告

据GIR (Global Info Research)调研,按收入计,2021年全球微波等离子体CVD反应器收入大约 百万美元,预计2028年达到 百万美元,2022至2028期间,年复合增长率CAGR为 %。

MARKETRESEARCH的博客 1138

别再只调陀螺仪了!用OpenCV实现基于透视变换的EIS防抖,实测效果媲美手机

本文深入探讨了基于透视变换的EIS电子稳像技术,通过OpenCV实现高阶防抖算法,效果媲美主流手机厂商方案。详细解析了传统旋转平移模型的局限性,并展示了透视变换在复杂场景下的优势,包括数学原理、OpenCV实战代码及性能优化技巧,为视频防抖提供了专业解决方案。

weixin_42613501的博客 454

Java中的volatile

​ volatile是Java提供的一种轻量级的同步机制,在并发编程中,它也扮演着比较重要的角色。同synchronized相比(synchronized通常称为重量级锁),volatile更轻量级,相比使用synchronized所带来的庞大开销,倘若能恰当的合理的使用volatile,自然是美事一桩。为了能比较清晰彻底的理解volatile,我们一步一步来分析。首先来看看如下代码 上面这个例子,模拟在多线程环境里,t1线程对flag共享变量修改的值能否被t2可见,即是否输出 “-----flag被设置为

HGW的博客 2万+

DOA估计算法从原理到仿真——CBF、Capon、MUSIC算法

从原理出发理解并实现经典的DOA估计算法

m0_55845774的博客 1万+

volatile关键字详解

缓存一致性协议: 每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,当处理器要对这个数据进行修改操作的时候,会强制重新从系统内存里把数据读到处理器缓存里。在多线程环境下,CPU轮流切换线程执行,有可能某个线程修改了数据,准备回主内存,此时CPU切换到另一个线程修改了数据,并且写回到了主内存,此时就导致数据的不准确。的作用就是,当某个线程工作内存中的值与主内存中的值,如果不相同就会一直。

努力分享一些干货 1837

告别调参烦恼:用Simulink手把手实现自适应模糊PID温度控制(附模型下载)

本文详细介绍了如何使用Simulink实现自适应模糊PID温度控制,解决传统PID调参难题。通过模糊推理引擎动态调整PID参数,系统能自动适应不同工况,显著提升控制精度和响应速度。文章包含完整的建模步骤、参数优化技巧和工业应用扩展,并附赠可下载模型,帮助工程师快速掌握这一智能控制技术。

weixin_30872499的博客 154

车辆TBOX科普 第7次 TBOX技术深度解析:硬件架构与核心组件详解

摘要: TBOX(车载远程信息处理单元)是智能网联汽车的核心组件,承担数据采集、通信连接与安全交互等关键功能。其硬件架构以主控单元为核心,采用ARM架构处理器(如NXP i.MX系列)实现高效能低功耗处理,搭配DDR4/LPDDR5内存保障性能,eMMC/UFS存储确保数据可靠性。设计中需平衡车规级可靠性(AEC-Q100)、EMC兼容性及成本控制,同时集成通信、定位与安全模块。未来趋势聚焦异构计算、先进制程及功能安全(ASIL-D)与信息安全融合,推动TBOX向边缘计算节点演进。该技术是汽车智能化转型的重

IT深耕十余载,大道之简 863

volatile变量

声明一个volatile变量,并赋值 public class VolatileTest { static volatile int i; public static void main(String[] args){ i = 10; } } 看看加了volatile之后,编译出来的字节码有什么不同,执行 javap -verbose VolatileT...

weixin_39713838的博客 453

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Volatile与CAS的底层原理

Volatile与CAS的底层原理 引言:VOLATILE是JAVA中一个极其重要关键字,它保证的内存的可见性,但是并不能够保证原子性。而CAS是采用一种无锁的方式,解决VOLATILE所不能带来的原子性等这类问题。接下来,就讲讲VOLATILE与CAS吧! 一、volatile 在讲解 Volatile关键字之前,先上个小demo! private static volatile long ...

rekingman的博客 4366

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

测试volatile变量的读写性能

volatile变量与非volatile变量的区别在于,volatile变量每次读都需要去主内存读取最新的值,每次写也需要写回到主内存;非volatile变量允许在缓存中读写以加快计算速度。

@甘道夫@的专栏 3677

REG_OPTION_NON_VOLATILE

REG_OPTION_NON_VOLATILE: 该宏是RegCreateKeyEx函数的参数可选项。 LONG RegCreateKeyEx( HKEY hKey, LPCWSTR lpSubKey,  DWORD Reserved, LPWSTR lpClass, DWORD dwOptions, REGSAM samDesired,  LPSECURITY_ATTRI

DBA@Robin 4907

Volatile介绍

volatile类似于大家所熟知的const也是一个类型修饰符。volatile是给编译器的指示来说明对它所修饰的对象不应该执行优化。volatile的作用就是用来进行多线程编程。在单线程中那就是只能起到限制编译器优化的作用。所以单线程的童鞋们就不用浪费精力看下面的了。 没有VOLATILE的结果       如果没有volatile,你将无法在多线程中并行使用到基本变量。下面举一个我开发项目

lifeng5055的专栏 491

c语言volatile 结构体,volatile的陷阱

例:多次的间接指针引用考察如下代码:/* DMA buffer descriptor */struct bd {unsigned int state;unsigned char *data_buff;};struct devregs {unsigned int csr;struct bd *tx_bd;struct bd *rx_bd;};volatile struct devregs * con...

weixin_29963537的博客 3461

volatile深入分析( 什么时候使用volatile)

原文:http://blog.youkuaiyun.com/vernonzheng/article/details/8201744 volatile 变量提供了线程的可见性,并不能保证线程安全性和原子性。 什么是线程的可见性: 锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility)。互斥即一次只允许一个线程持有某个特定的锁

jinfeiteng2008的专栏 1万+

volatile的实现细节

JVM是由C++实现的。 ①JVM层面。 StoreStoreBarrier volatile写操作 StoreLoadBarrier LoadLoadBarrier volatile读操作 LoadStoreBarrier 也就是volatile操作前后都加了内存屏障。 StoreLoadBarrier上面是Store,下面是Load。 LoadStoreBarrier上面是Lo...

学亮编程手记 640

Volatile

内存可见性   volatile是Java提供的一种轻量级的同步机制,在并发编程中,它也扮演着比较重要的角色。同synchronized相比(synchronized通常称为重量级锁),volatile更轻量级,相比使用synchronized所带来的庞大开销,倘若能恰当的合理的使用volatile,自然是美事一桩。   为了能比较清晰彻底的理解volatile,我们一步一步来分析。首先...

m0_37163942的博客 4063
上一篇: Optional-------NPE
下一篇: 数据库基础知识-01:
ADCQprogrammer
博客等级 码龄7年 4粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值