首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

volatile关键字的使用

MSDN手册中对volatile关键字的解释: 大概的翻译: volatile关键字是一个类型限定符,用于声明一个对象可以通过其他语句(例如操作系统、硬件或并发执行的线程)在程序中进行修改...volatile关键字的两个功能: (1)防止编译器对汇编指令做顺序上的优化。 (2)防止寄存器存储变量的副本值。...ptr[c],eax int c=gdata;//mov dword ptr[c],eax //为了优化指令,编译器认为两次赋值中间没有对gdata进行赋值 //第二次对c赋值使用...关键字,防止寄存器 //存储变量的副本值 } 指令的调优 1.编译器对指令的调优 使用volatile关键字 void fun(int *a){*a=10;int b=*a;} //上述的代码...(volatile int* a){*a=10;int b=*a} 2.程序执行时cpu对指令的调优 barrier() 当程序开始执行时,由于CPU的流水线技术,可能会对指令进行顺序上的调优。

26630
您找到你想要的搜索结果了吗?
是的
没有找到

什么时候应该使用volatile

volatile 修饰符告诉编译程序不要对该变量所参与的操作进行某些优化。...在两种特殊的情况下需要使用volatile 修饰符:第一种情况涉及到内存映射硬件(memory-mapped hardware,如图形适配器,这类设备对计算机来说就好象是内存的一部分一样),第二种情况涉及到共享内存...(shared memory,即被两个以上同时运行的程序所使用的内存)。...例如,为了调整某个操作的时间,可能会用到下述函数: time_t time_addition(volatile const struct timer * t, int a){ int n; int...如果不使用volatile 修饰符,一个聪明的编译程序可能就会认为t->value 在该函数执行期间不会改变,因为该函数内没有明确地改变t->value 的语句。

2K30

volatile

精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。    ...程序的本意是希望ISR_2中断产生时,在main当中调用dosomething函数,但是,由于编译器判断在main函数里面没有修改过i,因此   可能只执行一次对从i到某寄存器的读***作,然后每次if判断都只使用这个寄存器里面的...一般说来,volatile用在如下的几个地方:   1、中断服务程序中修改的供其它程序检测的变量需要加volatile;   2、多任务环境下各任务间共享的标志应该加volatile;   ...volatile 的含义    volatile总是与优化有关,编译器有一种技术叫做数据流分析,分析程序中的变量在哪里赋值、在哪里使用、在哪里失效,分析结果可以用于常量合并, 常量传播等优化,进一步可以死代码消除...但有时这些优化不是程序所需要的,这时可以用volatile关键字禁止做这些优化,volatile的字面含义 是易变的,它有下面的作用:   1 不会在两个***作之间把volatile变量缓存在寄存器中

50770

volatile

volatile关键字的字节码原语 1、volatile使用场景: DCL单例模式的对象创建的过程(申请内存空间,初始化对象,引用指向对象的内存空间地址这三个操作不是原子操作,会发生指令重排,所以加上volatile...lock; addl $0,0(%%rsp) 其中的addl $0,0(%%rsp) 是把寄存器的值加0,相当于一个空操作(之所以用它,不用空操作专用指令nop,是因为lock前缀不允许配合nop指令使用...) lock前缀,会保证某个处理器对共享内存(一般是缓存行cacheline,这里记住缓存行概念,后续重点介绍)的独占使用。...因为CPU和其他部件进行通信都是通过总线来进行的,如果对总线加LOCK#锁的话,也就是说阻塞了其他CPU对其他部件访问(如内存),从而使得只能有一个CPU能使用这个变量的内存。...最出名的就是Intel 的MESI协议,MESI协议保证了每个缓存中使用的共享变量的副本是一致的。

54600

volatile

不知朋友们在编写多线程代码时,对于共享内存变量是否很好的处理呢,接下来我们将介绍volatile语义、特性、和使用。...因为volatile变量的值每次都需要从高速缓存或者主内存中读取,而无法被暂存在寄存器中,从而无法发挥访问的高效性。 2.4.4 volatile应用场景 使用volatile变量作为状态标志。...此时使用volatile的好处是一个线程能够‘通知’另外一个线程某种事件的发生,而这些线程又无须因此而使用锁,从而避免了使用锁的开销。...使用volatile保障可见性,使用final也可以保证数据内存的可见性(由于章节设计不对final进行分析)。...使用volatile变量替代锁。volatile变量并非锁的替代品,但是在一定的条件下他比锁更合适。

50320

volatile使用与原子性问题

1. volatile使用 java源代码 public class VolatileUsedClass { private static int sharedVar = 10;...有volatile修饰的执行结果(多次) ? 结果分析 不带volatile修饰与客户端执行效果一致 但是使用server模式带有volatile的方式却出现了数据不一致的情况,为什么?...原子性问题 说明: 以下运行环境是使用-client模式进行,排除重排序的干扰 Java中的原子性 jdk文档对于原子性的说明如下: 除了long和double类型之外,引用变量与大多数的原始数据类型都具备读写操作的原子性...所有使用volatile修饰的变量都具备读写操作的原子性 分析 针对64bit的数据类型,主要与处理器(32bit/64bit)有关,在32bit处理器上,JVM会将64bit的long/double...在这里是保证代码刷新到主内存,对于sharedVar = const 是具备原子性的 使用volatile小结 对变量进行写操作的时候可以通过volatile来实现对其他线程的可见,同样在单步指令操作中是具备原子性

53040

volatile

volatile基于JMM happens-before原则 参考 volatile与指令重排序 并发关键字volatile(重排序和内存屏障) 单线程中,JVM会在不影响语义的情况下,对指令进行重排序...volatile volatile的作用: 避免指令重排。volatile关键字通过提供“内存屏障”的方式来防止指令被重排序。 保证可见性。...若加上volatile,根据 ?...volatile写之前,代码中其之前的所有读写已经完成 volatile读之前,代码中其之前的所有volatile读写已经完成 instance的读之前,instance的写入动作1和动作2一定已经完成...volatile提供的可见性,是说每个线程访问用volatile修饰的变量时,volatile都保证线程能从主存区加载到当前最新的值(反之,线程修改后同步到主存的值也要保证对其他线程的可见); java

54960

volatile 关键字了解与使用

但这里有个误区,这样的使用方式容易给人的感觉是: 对 volatile 修饰的变量进行并发操作是线程安全的。 这里要重点强调,volatile 并不能保证线程安全性!...//使用 volatile 修饰基本数据内存不能保证原子性 4 5 //private static AtomicInteger count = new AtomicInteger() ; 6...也可以使用 synchronize 或者是锁的方式来保证原子性。 还可以用 Atomic 包中 AtomicInteger 来替换 int,它利用了 CAS 算法来保证了原子性。...,JVM 对 1 和 2 进行重排,导致 value 都还没有被初始化就有可能被线程 B 使用了。...指令重排的的应用 一个经典的使用场景就是双重懒加载的单例模式了: 1 public class Singleton { 2 3 private static volatile Singleton

26420

为什么volatile使用比synchronized少

在多线程编程中,我们最常用的是synchronized,而对volatile使用,却相对较少。这一方面是因为volatile使用场景限制,另一方面是volatile使用需要更高的技术水平。...而volatile恰恰可以解决这个可见性的问题,当变量被volatile修饰,如private volatile int stateFlag = 0; 它将直接通过主内存中被读取或者写入,线程从主内存中加载的值将是最新的...但是volatile使用有着严格的限制,当对变量的操作依赖于以前值(如i++),或者其值被其他字段的值约束,这个时候volatile是无法实现线程安全的。...综上所述,由于volatile只能保证变量对多个线程的可见性,但不能保证原子性,它的同步机制是比较脆弱的,它在使用过程中有着诸多限制,对使用者也有更高的要求,相对而言,synchronized锁机制是比较安全的同步机制...,有时候出于提高性能的考虑,可以利用volatile对synchronized进行代替和优化,但前提是你必须充分理解其使用场景和涵义。

48280

Java中volatile关键字的使用

放心在Java中还提供了一个关键字来解决类似上述问题所产生的线程安全,它就是volatile关键字。这也是我在文章开头所说的。volatile关键字的作用就是使变量在多个线程间可见。...那我们简单点说明就是用volatile关键字修饰的变量只能保存在主内存中,或者说线程在使用volatile数据时只能去主内存中是取值。...也可以理解为每个线程在拷贝主内存数据到自己的线程内存时,volatile关键字修饰的变量是拷贝不了的。...这也就保证了无论有多少个线程,如果它们需要使用volatile关键字修饰的变量,那只能去主内存中是取值。...在实际的开发中volatile关键字在多线程中我们经常使用。 ?

78820

Java并发编程——volatile关键字使用

首先思考,volatile关键字是用来干什么的?...volatile可以用来解决可见性和有序性的问题 首先看一下什么是可见性: 定义一个boolean型变量,然后阿巴阿巴阿巴阿巴(看代码看代码) 代码示例: 执行以上代码,大家猜结果是什么?...而当我们在stop上加上volatile关键字之后: 该线程就捕捉到了stop值的改变 (结果为付是因为结果超出了int的最大值) 换句话说,volatile关键字使这个变量在线程间变成了互相可见的...这里放出原理,不过是汇编层面的,大家当面试题记一下就好,不必深入追究 加了volatile关键字的变量,在字节码文件里,变量前面会加一个lock指令 那么,我们什么时候需要用到volatile...就如同上面那个例子一样 当存在多个线程对同一个共享变量进行修改的时候,需要增加volatile,保证数据修改的实时可见 本质上来说,volatile关键字实际上是通过内存屏障来防止指令重排序以及禁止

18520

volatile禁止指令重排序_volatile int

volatile禁止指令重排 JMM要求有序性 计算机在执行程序时,为了提高性能,编译器和处理器常常会做指令重排,一把分为以下3种 单线程环境里面确保程序最终执行结果和代码顺序执行的结果一致....(单线程不用关心指令重排) 处理器在进行重新排序是必须要考虑指令之间的数据依赖性 多线程环境中线程交替执行,由于编译器优化重排的存在,两个线程使用的变量能否保持一致性是无法确定的,结果无法预测 源码写的顺序不见得和编译的指令顺序一样...如果编译器对这段代码进行执行重排优化后,可能出现下列情况: 线程1 线程2 b=1; a=2; x=a; y=b; 结果: x=2 y=1 这也就说明在多线程环境下,由于编译器优化重排的存在,两个线程使用的变量能否保持一致是无法确定的...例子3 两个线程分别执行method1 和method2 多线程环境中线程交替执行,由于编译器优化重排的存在,两个线程使用的变量能否保持一致性是无法确定的,结果无法预测 假设线程1首先执行method1...所以指令重排会造成值不一致,所以有时候我们需要 volatile禁止指令指令重排 总结(了解) PS:学习笔记,资源:尚硅谷,周阳 版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。

35740

volatile解读

关键字volatile在Java中本质上是一种修饰符,它用来修饰变量。 volatile关键字在多线程编程中非常重要,它保证了多个线程之间变量的可见性和有序性。...volatile修饰变量的特性 可见性 被volatile修饰的变量对于所有线程都是可见的,即当一个线程修改volatile变量的值后,其他线程立即可见修改后的值。...而在多线程环境中,这种指令重排序可能会导致程序输出不正确的结果,因此使用volatile关键字可以禁止指令重排序优化。...对于需要具备原子性的操作,需要使用synchronized关键字或者使用Java.util.concurrent.atomic包中的原子类。...volatile 写之前的操作,都禁止重排序到volatile之后 volatile 读之后的操作, 都禁止重排序到 volatile之前 volatile写之后volatile读,禁止重排序

14250

Java 并发编程:volatile使用及其原理

Synchronized原理有了解的话,应该知道Synchronized是一个比较重量级的操作,对系统的性能有比较大的影响,所以,如果有其他解决方案,我们通常都避免使用Synchronized来解决问题...二、volatile使用   关于volatile使用,我们可以通过几个例子来说明其使用方式和场景。 1、防止重排序   我们从一个最经典的例子来分析重排序问题。...三、volatile的原理   通过上面的例子,我们基本应该知道了volatile是什么以及怎么使用。现在我们再来看看volatile的底层是怎么实现的。...为了实现volatile内存语义,JMM会对volatile变量限制这两种类型的重排序。...的理解还是比较困难的,如果不是特别理解,也不用急,完全理解需要一个过程,在后续的文章中也还会多次看到volatile使用场景。

43150
领券