volatile

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

一、内存模型
1、关于内存
​ CPU处理速度很快,但它数据来源于内存,cpu向内存拿数据的这个过程是相对耗时的,这就会造成cpu资源浪费,为了解决这一问题,现在的处理器一般在cpu与内存之间建立多级缓存,一级缓存在cpu里也叫寄存器(高速缓存),当他处理数据时先从寄存器拿,拿不到再去内存里取。目前计算机大部分都是多核cpu,每个cpu都有自己的寄存器,但他们共享内存,当一个cpu改变了他自己缓存里的值并同步到内存后,其他cpu缓存里的值不是最新的,跟内存值不一样,这就是缓存一致性问题。

​ Java内存模型主要目标是定义程序中变量的访问规则。这里的变量主要是指方法区和堆中的对象,因为虚拟机栈中的方法和变量是线程私有的,在多核并发的时候堆中的变量(对象)在多个线程中被使用,可能导致该变量在每个线程中的值不一样,影响到我们的业务。

​ cpu与内存的关系映射到多线程中可以看作是工作内存和主内存的关系,一个cpu处理一个线程就是一个工作内存。主内存:可以理解成堆;工作内存:是线程私有,可以理解成虚拟机栈。工作内存里是主内存中变量的副本,线程对主内存变量值的修改必须在自己的工作内存中进行,不能直接更改主内存变量。线程之间需要传递变量值也是借助主内存作为中介进行的。
在这里插入图片描述

​ 2、三个特性

并发编程要重点关注内存模型的三个特性:可见性、原子性、有序性

可见性:线程之间对内存模型的数据是可见的,A线程修改了内存里的值,B线程能够及时拿到最新的值。

原子性:类似于数据库事务,是一个最小的操作单元,不能再被分割了。我们代码中常见的变量赋值操作:int a=2;这就是不可再分的;而int a=b;i++这种就不是原子操作,他们要先取值再赋值。

有序性:处理器为了提高运行效率会对代码进行指令重排序,在数据没有依赖性的情况下发生指令重排序时单线程没问题,多线程情况下指令重排序就可能引起问题,一个线程里先走a还是先走b都没问题,但是另一个线程里可能就必须要走了a才能用b的值。如:a是初始化方法,b是一个初始成功的变量,在另一个线程里要用到初始化方法,就先判断b是否成功,这种情况下就会导致程序不正确了。

二、volatile

volatile是Java的一个关键字,用法很简单,直接修饰变量。被volatile修饰的变量能够保证2个特性:可见性和有序性(禁止指令重排序)。

可见性:修改了被volatile修饰的变量值后会被立即写入主内存,同时通知其他cpu里缓存的该变量值无效,让他们重新从内存中取值。保证可见性是通过缓存一致性原理实现的。

有序性:被volatile修饰后,该变量前后的代码会禁止指令重排序。它是通过内存屏障实现的,因为不会发生重排序,所以会对性能有一点影响。禁止指令重排序是通过内存屏障实现的。

​ volatile的实现原理很简单,它通过一个lock前缀指令来保证可见性。对于变量的写操作,一定会同步刷新到主内存;读操作,一定是从主内存中取最新的值。

​ volatile不能保证原子性,如果要保证原子性需要用锁(synchronized、lock)或者并发包提供的安全的原子操作类。

关于volatile的应用:

​ 平时开发我们用到的概率很小,顶多标记一个状态量是true还是false,以此来决定后续的流程走还是不走。

​ 在jdk中常见的应用有:

​ 与cas结合实现原子性。

​ 单例模式创建时的双重检查(Double Check)

public class Singleton2 {
    private Singleton2(){};
    //单例对象被volatile修饰
    private static volatile Singleton2 singleton2 = null;
    public static Singleton2 getSingleton2(){
        if(singleton2==null){
            synchronized (Singleton2.class){
                if(singleton2==null){
                    singleton2 = new Singleton2();
                }
            }
        }
        return singleton2;
    }
}
深入分析Volatile的实现原理 本文将深入分析在硬件层面上Inter处理器是如何实现Volatile的,通过深入分析能帮助我们正确的使用Volatile变量。 立即下载

相关推荐

一文读懂AI大模型时代的RAG技术

RAG(Retrieval-Augmented Generation,检索增强生成) 是一种结合检索技术与生成模型的技术架构,旨在通过动态引入外部知识库增强大语言模型(LLM)的生成能力。其核心思想是通过检索系统从外部数据源(如企业知识库、实时文档等)获取相关信息,并将检索结果作为上下文输入生成模型,以提高生成答案的准确性、时效性和专业性

awei0916的专栏 2118

volatile详解

volatile的三大特性,以及应用场景

weixin_46120888的博客 5790

stm32f407等芯片(HAL库)时钟频率修改(乱码)

其他片子及库文件未知、未验证,只是在使用stm32f407ZG配置串口打印的时候,出现乱码,就从以下几方面定位问题: 1. 确认串口GPIO相关配置; 2. 确认波特率等参数; 3. 确认时钟频率; 结果这次使用YH的串口打印程序在ZDYZ的开发板调试项目工程(有点另类...),做功能验证,就出现了以上问题,出于好奇开始调试,最终发现是时钟频率问题。 看到下图这个配置,因为ZDYZ开发板使用的是8MHz外部晶振(好像默认的是25MHz,如图2),所以他这里PLL_M是25,不是推荐值,感...

bulefire2009的博客 5514

volatile 关键字

volatile是一种同步机制,类似于 Lock 和 Synchronized ,但是他更轻量级,因为使用 volatile 并不会发生上下文切换等开销很大的行为。如果一个变量被volatile修饰,那么JVM会认为这个变量可能会被并发修改,会保证关于这个变量的修改能立即被其他线程看到。因为开销小,所以能力也小;他做不到像 synchronized 那样的原子保护,使用的场景比较有限。

Qynwang的博客 2106

php对接建行h5网页支付

php对接建行h5网页支付前言H5页面支付H5页面支付回调通知退款及其他的业务 前言 最近接到公司乙方要求,需要再支付上面增加建行的支付渠道。之前一直用的都是微信和支付宝这种第三方支付平台,银行直接对接比较少。没办法就只能上网搜索,搜索一番返现网上对接建行的资料比较少,没办法只好摸着石头过河,中间也借鉴了一些大佬的文章内容。 H5页面支付 根据建行的h5网页支付对接文档,还是可以看出是比较简单的。...

lihua100862的博客 5408

2024从零开始使用VSCode编程(静态页面制作篇)HTML+CSS+JS阶段

VSCode第一个前端静态页面的编写

ssrsrrn的博客 9590

volatile 原理

volatile 是 Java 提供的一种轻量级的同步机制。Java 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量,相比于synchronized(synchronized通常称为重量级锁),volatile更轻量级,因为它不会引起线程上下文的切换和调度。但是volatile 变量的同步性较差(有时它更简单并且开销更低),而且其使用也更容易出错。

小鲁蛋的博客 3275

Western blot (WB) 灰度分析进阶指南:ImageJ 高效定量技巧与实战优化

本文详细介绍了使用ImageJ进行Western blot灰度分析的进阶技巧,包括批量处理、背景校正和疑难条带处理等实战优化方法。通过自动化宏脚本和动态背景校正,显著提升分析效率和准确性,特别适合科研人员处理复杂WB数据。

weixin_42557830的博客 899

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

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

成都彭于晏 2万+

Nexus3国内高速下载指南:多版本全平台资源汇总

本文针对国内开发者从官网下载Nexus 3速度慢、易失败的问题,提供了详尽的解决方案。汇总了Windows、Linux、macOS等多个平台的Nexus 3历史及最新版本(如3.31.1)的国内高速下载链接,并附有版本选择建议与Linux环境下的快速启动指南,帮助用户高效获取和部署这一流行的仓库管理工具。

jwt8token的博客 431

电机驱动和电源等大电流设计中的并联 MOSFET设计

在电机驱动等应用中,半桥拓扑(通常为 3 相)用于生成在电机中产生正扭矩或负扭矩的交流电源信号。想要更高的输出电流能力,只有通过并联形成每个功能开关的 MOSFET,才能实现高输出电流。当多个功率 MOSFET 并联以增加系统整体电流能力容量时,通常假设电流在并联器件之间均等分配或均等共享。然而,在并联 MOSFET 时,需要考虑并联器件之间的电流分配。PCB 布局的若干特性和特定的MOSFET 参数会影响这种分配,并在参数不匹配或布局不对称时导致均流不平衡。

小幽余生不加糖 2485

Java中的volatile

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

HGW的博客 2万+

Win11更新导致TIA博途许可证出现问题的解决办法汇总

Win11更新导致TIA博途许可证出现问题的解决办法汇总

Robot_PLC_HMI_Automation 9890

volatile关键字详解

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

努力分享一些干货 1837

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

volatile变量

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

weixin_39713838的博客 452

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Volatile与CAS的底层原理

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

rekingman的博客 4366

测试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的专栏 490
上一篇: Thread 线程
下一篇: synchronized
csdn_binger
博客等级 码龄11年 2粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值