volitile变量的使用

Java volatile关键字最全总结:原理剖析与实例讲解(简单易懂) 本文从Java的内存模型和线程的工作原理出发,对volatile关键字进行介绍。帮助读者深入理解volatile的工作机制。同时,还通过简单易懂的示例讲解了如何正确地使用volatile关键字实现线程安全,避免常见的多线程安全问题。 阅读详情

volatile 影响编译器编译的结果,指出 volatile 变量每次使用时都需要去内存里重新读取它的值,而一旦修改此变量就直接写入内存,而不是操作cache中的变量。 volatile 变量有关的运算,不要进行特殊优化。

{

int I = 10;

int j = I;

int k=I;

}

对于上面的代码段,优化的作法是,编译器发现两次从 i 读数据的代码之间的代码没有对 i 进行过操作,它会从 cache 中把上次读的数据 i 放在 k 中。而不是重 新从 i 的内存里面读。这样以来,如果 i 是一个寄存器变量或者表示一个端口数据就容易出错,所以说 volatile 可以保证对特殊地址的稳定访问,不会出 错。

我们来看另一个例子

int volatile I;

while(i)

{

    do_something();

}

如果 i 没有被 volatie 修饰,当 while 循环执行时,另一段程序并发的执行了 i=0 ,这个循环仍不会退出,因为每次循环都是检查寄存器中的值。 如果有 volatie 修饰,那么循环结束,因为循环每次检查 i 的时候,会先从内存把 i 读入寄存器,这个时候 i 在其它地方被赋 0 ,则循环结束。    

对于程序中存在多个执行流程访问同一全局变量的情况, volatile 限定符是必要的。

此外,虽然程序只有单一的执行流程,但是变量属于以下情况之一的,也需要 volatile 限定。

1 变量的内存单元中的数据不需要写操作就可以自己发生变化,每次读上来的值都可能不一样

2 即使多次向变量的内存单元中写数据,只写不读,也并不是在做无用功,而是有特殊意义的

什么样的内存单元会具有这样的特性呢?肯定不是普通的内存,而是映射到内存地址空间的硬件寄存器,例如串口的接收寄存器属于上述第一种情况,而发送寄存器属于上述第二种情况。      

因此建议使用 volatile 变量的场所:

1 并行设备的硬件寄存器

2  一个中断服务子程序中会访问到的非自动变量(全局变量)

3 多线程应用中被几个任务共享的变量

4 longjmp跳回之后需要保持修改的变量

 

上面的代码分别在非优化和优化条件下将得到不同的结果。

在嵌入式或多线程的环境下,不懂得 voliatile 可能会导致灾难。我们通过下面几个问题来加深对其理解。

关键字 volatile 有什么含意 ? 并给出三个不同的例子
         1) 一个参数既可以是 const 还可以是 volatile 吗?解释为什么。

是的。一个例子是只读的状态寄存器。它是 volatile 因为它可能被意想不到地改变。它是 const 因为程序不应该试图去修改它。(也就是说, const 指定了我们的程序代码中是不可以改变这个变量的, 但是 volatile 指出,可以是由于硬件的原因,在代码意外更改这个值,但是我们的代码同时会更新使用这个最新的数值)

2) 一个指针可以是 volatile 吗?解释为什么。

是的。一个例子是当一个中服务子程序修该一个指向一个 buffer 的指针时。(把指针声明为 volatile 的类型,可以保证指针所指向的地址随时发生变化)

3) 下面的函数有什么错误:

 int square(volatile int *ptr) {
              return *ptr * *ptr;
         }

这段代码的目的是用来返指针 *ptr 指向值的平方,但是,由于 *ptr 指向一个 volatile 型参数,编译器将产生类似下面的代码:
         int square(volatile int *ptr){
              int a,b;
              a = *ptr;
              b = *ptr;
             return a * b;

}

由于 *ptr 的值可能被意想不到地该变,因此 a 和 b 可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
         int square(volatile int *ptr){
                 int a;
                 a = *ptr;
                return a * a;
         }

在 signal.h 头文件中声明了一种 sig_atomic_t 的类型,当把变量声明为该类型是,则会保证该变量在使用或赋值时, 无论是在 32 位还是 64 位的机器上都能保证操作是原子的, 它会根据机器的类型自动适应。 通常情况下, int 类型的变量通常是原子访问的,在 linux 里这样定义: typedef int __sig_atomic_t; 另外 gnu c 的文档也说比 int 短的类型通常也是具有原子性的,例如 short 类型。同时,指针(地址)类型也一定是原子性的。在 32 位的平台下,访问 64 位的变量,就不是原子的,而需要两次读内存操作。 sig_atomic_t 类型的变量应该总是加上 volatile 限定符 ,因为要使用 sig_atomic_t 类型的理由也正是要加 volatile 限定符的理由。  

川崎机器人 AS语言基础运动指令表     功能简介 动作方式 参考坐标系 位置特性 X,Y,Z 角度特性 O,A,T 指令格式(距离单位毫米,时间单位秒,角度单位度 示例1 示例2 运 动 指 令 JMOVE 以关节移动到目标点 关节移动方式 基础坐标系 不受控 伪随机动作 JMOVE 目标点 JMOVE #yd JMOVE put1 LMOVE 以直线移动到目标点 直线移动方式 阅读详情

相关推荐

双有源桥DC-DC变换器:原理、软开关与移相控制深度解析

隔离型DC-DC变换器是电力电子系统的核心部件,通过高频变压器实现电气隔离与电压匹配,保障系统安全与灵活适配。其工作原理基于功率半导体器件的开关动作,通过调制策略控制能量传输。该技术的核心价值在于实现高效、高功率密度的电能转换,并支持双向能量流动,这对于提升系统整体能效和运行灵活性至关重要。在新能源储能、电动汽车V2G及数据中心供电等场景中,双向能量流成为刚性需求,推动了如双有源桥等先进拓扑的应用。本文聚焦于双有源桥这一实现高效双向隔离变换的“明星”方案,深入剖析其利用移相控制实现软开关的机理。通过分析谐振

weixin_34195142的博客 378

volatile与const的实际使用

volatile与const的使用 #define __I volatile const /*!< defines 'read only' permissions */ #define __O volatile /*!< defines 'write only' permissions */ #define __IO volatile /*!&

weixin_46662102的博客 321

小红书x-mini签名逆向实战:Frida动态Hook与算法还原

在移动App协议分析中,请求签名机制是保障接口安全的核心技术,其本质是客户端对请求参数、时间戳、设备指纹等要素进行加密认证的过程。理解签名原理需掌握Native层加密流程、JNI调用机制及密钥动态派生逻辑。Frida作为主流动态插桩工具,能绕过符号剥离、字符串加密和控制流混淆等反分析手段,在函数执行瞬间捕获寄存器状态、内存数据与调用上下文,实现签名算法的完整还原。该技术广泛应用于合规内容监测、API自动化调用与竞品协议研究等工程场景。本文聚焦小红书x-mini签名这一典型样本,详解从JNI_OnLoad定位

weixin_31264565的博客 457

【002 关键字】一文彻底搞懂volatile用法

一、常见说法 volatile 关键字和const对应,一样是一种类型修饰符,用它修饰的变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。············ 二、volatile作用 1、 举例说明作用 int i=10; int j =..

kashine的博客 1万+

告别OpenAI API调用:手把手在本地CPU/GPU上部署fast-whisper中文语音识别模型

本文详细指导如何在本地CPU/GPU上部署fast-whisper中文语音识别模型,摆脱对OpenAI API的依赖。从环境准备、模型获取与优化,到CPU/GPU环境的具体部署步骤和性能优化技巧,全面覆盖本地化语音识别的实现方案,帮助开发者提升效率并保障数据隐私。

weixin_29988907的博客 306

如何通过插值法计算cell delay?

插值法的公式:Z = A + B * X + C * Y + D * X * Y,其中X为input transition,Y为output load,A、B、C、D为四个参数,Z为delay值。从而得到Z=-0.086176 + 11.5493 * x + 0.65917 * y - 24.859 * x * y,当X=0.014930、Y=0.296311时,得到Z=0.1716ns。从而得到A = 0.08075,B = 3.47539,C = 0.04008,D = 0.01648。

芯冰乐 1076

volatile解读

被volatile修饰的变量对于所有线程都是可见的,即当一个线程修改volatile变量的值后,其他线程立即可见修改后的值。写完后立即刷新回主内存并及时发出通知,大家可以去主内存拿最新版,前面的修改对后面所有线程可见,

一个菜鸡的博客 1056

知识图谱实战应用8-从文本关系抽取到知识图谱关系构建流程贯通

大家好,我是微学AI,今天给大家介绍一下知识图谱实战应用8-从文本关系抽取到知识图谱关系构建流程贯通。我们从文本数据中采集到关键信息,并抽取出其中的关系信息,然后在存入图数据库中,整个过程实现自动化,我这里将举一个文本例子进行抽取。 对于知识图谱的构建是将实体、概念和它们之间的关系都以图表形式呈现出来的一种数据结构。要构建一个知识图谱,需要从不同的数据源中采集到相关信息,并将这些信息整合在一起,最终形成一个全面而且精确的知识图谱。

微学AI的博客 2545

Java中的volatile

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

HGW的博客 2万+

Arduino ESP32S3开发环境搭建 ------ 在线下载安装包Failed解决方案

本文介绍了Arduino ESP32 S3开发环境搭建的离线解决方案。

张一西的博客 1018

飞牛fnNAS同步微信微信聊天记录

微信聊天记录如何备份到NAS?本文介绍了利用NAS虚拟机和同步工具实现微信记录自动备份的方法。通过在NAS上搭建"云电脑"长期运行微信PC端,并配置微力同步将聊天记录文件夹自动同步到NAS存储,解决了传统电脑备份的安全性问题。操作步骤包括:1)在NAS上安装虚拟机系统;2)登录微信PC端并同步手机记录;3)配置同步工具将微信记录文件夹同步到NAS。该方法尤其适合不常使用PC微信的用户,可实现记录永久保存和远程查看,更换手机时也能快速恢复历史记录。

dgnankai的专栏 4303

Java 多线程-- 锁

一 CAS ( 比较并交换 ) compare-And-Swap shi CPU 原子指令,汇编指令 不会造成数据不一致 :自旋锁 ,Unsafe AtomicInteger : CAS缺点:保证一致性,但需要多次比较 ;循环时间长,开销大。只能保证一个变量的原子操作,。同时引出ABA问题, 二. volitile 避免指令重排,同步更新数据,应用于单例模式 三 .java 资源共享 ...

yingwuluohan的专栏 183

YOLOv11改进 | 损失函数改进篇 | 2024最新高质量的目标检测边界框回归损失Unified-IoU、FocalUIoU、FocalInvUIoU(设置动态epoch参数)

本文给大家带来的改进机制是最近新提出的高质量的目标检测边界框回归损失,其通过动态调整模型对不同质量预测框的关注,优化目标检测中的边界框回归精度。UIoU引入了FocalBox方法,通过缩放预测框与真实框分配权重,并采用了退火策略(引入动态参数epoch),逐渐将模型的注意力从低质量预测框转移到高质量预测框,平衡了训练速度与检测精度。其还有一定的解决样本不平衡问题,同时该损失函数可以和现有的任何边界框回归损失函数进行结合,例如ShapeIoU和其结合可以形成二次创新,它是一种类似于之前的Inner的机制.

Snu77的博客 4584

Java 多线程 volitile 和 atomic

Java 多线程 volitile 和 atomic volitile关键字 public class MTester { public static class TestKey{ int x = 0; } public static TestKey key0 = new TestKey(); public static void main...

aammmmo6653的博客 238

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

说说volitile关键字

此时如果一个变量的值同时被缓存在两个CPU即CPU0和CPU1的高速缓存中,当CPU0修改了这一共享变量的值并同步到主存中,CPU1需要从内存中获取最新的值但获取时机是不确定的,这就会导致缓存一致性问题,解决缓存一致性问题的方法是使用总线锁或缓存锁,缓存锁能够保证缓存一致性是因为其中使用的缓存一致性协议(MESI),MESI表示缓存的四中状态即修改,共享,独占,失效,该协议的核心是修改一个共享的数据时,需要先使其它处于共享状态的缓存失效。对齐填充主要是为了解决伪共享的问题。

m0_52242788的博客 502

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

volitile的使用

volatileche称为轻量级锁,被volatile修饰的变量,在线程之间是可见的。可见:一个线程修改了这个变量的值,在另一个线程中能够读到这个修改后的值synchronized除了线程之间互斥,还有一个非常大的作用,就是保证可见性 1 /* 2 * 保证可见性的前提 3 * 4 * 多个线程拿到同一把锁,否则保证不了 5 * 6 */ 7 publ...

weixin_33809981的博客 182

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

JUC7 volitile

①. 内存屏障(也称内存栅栏,内存栅障,屏障指令等,是一类同步屏障指令,是CPU或编译器在对内存随机访问的操作中的一个同步点,使得此点之前的所有读写操作都执行后才可以开始执行此点之后的操作),避免代码重排序。内存屏障其实就是一种JVM指令,Java内存模型的重排规则会要求Java编译器在生成JVM指令时插入特定的内存屏障指令,通过这些内存屏障指令,volatile实现了Java内存模型中的可见性和有序性,但volatile无法保证原子性。②. 内存屏障之前的。2.2.1 粗分两种。2.2.2 细分四种。

457

Volitile关键字

保证可见性:即保证了不同线程对这个变量的可见性,即一个线程修改了本变量的值,对其他线程来说是立即可见的 禁止进行指令重排序,保证线程的有序行. 保持内存可见性 内存可见性(Memory Visibility):所有线程都能看到共享内存的最新状态。 失效数据 以下是一个简单的可变整数类: public class MutableInteger { private int value; public ...

weixin_38914772的博客 518

关于volitile相关知识

volitile重排序相关解释 对volitile变量的写入操作之后要保证不能和读之后的读操作重排序。这是内存重排序的一种解决方案happenbeforr中规定的底层通过刚开始讲的内存屏障保证不会重排序。 volitile是通过happenbefore原则保证的。 普通变量的写入和读取再各个线程都有自己的缓存不能够及时同步到主存中,因此多线程下会出现问题,单线程不会出现问题是因为if-else-serial原则保障在单线程环境下即使重排序也不会改变运行的结果;但是它并没有规定多线程环境下。 重排序分类 后来

北洋的博客 731

volatile的变量学习

3 “做饭”指令执行完毕,具体指的是饭做好了,而且必须盛到碗里而不是还放在锅里,保证干饭人来了后必须立刻能吃到饭。重排指令可能会导致功能出错?编译器可能会重排指令?CPU也可能会重排指令。2 “叫吃饭”时,一定要保证“做饭”指令执行完毕;1 “做饭”和“叫吃饭”的指令不能乱序;

bdfpxsfh的专栏 155

const、volitile和static

const: 1、如果把const放在变量类型前,说明这个变量的值是保持不变的(即为常量),改变量必须在定义时初始化,初始化后对她的任何赋值都是非法的。 2、当指针或是引用指向一个常量时,必须在类型名前使用const标示这个指针或是引用指向的“变量”为常量,没有的话就是语法错误。 3、假如变量是一个非常量变量,而指针或者引用的类型名前使用了const,那么可以直接修改变量,不能通过指针或者引...

weixin_30488313的博客 112

c语言中的volitile用法

volatile 影响编译器编译的结果,指出,volatile 变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以免出错,(VC++ 在产生release版可执行码时会进行编译优化,加volatile关键字的变量有关的运算,将不进行编译优化。)。 例如: volatile int i=10; int j = i; ... int k = i; volati...

xingzhe22222的博客 828

volitile 关键字的作用,原理

volatile关键字的作用、原理 在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到“半个”单例。 而发挥神奇作用的volatile,可以当之无愧的被称为Java并发编程中“出现频率最高的关键字”,常用于保持内存可见性和防止指令重排序。 保持内存可见性 内存可见性(Memory Visibility):所有线程都能...

qq_33398459的博客 1144

对于volitile的总结:

Volatile关键字

个人专长:数据结构和算法、大数据、数据库、主流框架 149

java volitile关键字

转自https://www.cnblogs.com/dolphin0520/p/3920373.html //线程1 boolean stop = false; while(!stop){ doSomething(); } //线程2 stop = true; 第一:使用volatile关键字会强制将修改的值立即写入主存; 第二:使用volati...

dengfeng6722的博客 258

java中volitile关键字的意思

原文链接点击打开 我们知道,在Java中设置变量值的操作,除了long和double类型的变量外都是原子操作,也就是说,对于变量值的简单读写操作没有必要进行同步。 这在JVM 1.2之前,Java的内存模型实现总是从主存读取变量,是不需要进行特别的注意的。而随着JVM的成熟和优化,现在在多线程环境下volatile关键字的使用变得非常重要。 在当前的Java内存模型下,线程

wyj880220的专栏 1288
上一篇: Linux错误号(errno)对应错误一览
下一篇: Linux下网络流量实时监控
zzulp
博客等级 码龄19年 464粉丝 176原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值