volatile

阅读 / 问答 / 标签

PIC单片机的volatile定义的地址到底有什么作用

/******************************************************************************************************************** 一看给就是C语言没有学好,voatile 是易变的、不稳定的意思,volatile是一种类型修饰符,用它修饰变量表示可以被某些编译器未知的因素更改,不如操作系统硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。 先看看下面的例子: volatile int i=10; int j = i ;//(3) 语句 int k = i;//(4) 语句volatile关键字告诉编译器i 是随时可能发生变化的,每次使用它的时候必须从内存中取出i的值,因而编译器生成的汇编代码会重新从i 的地址处读取数据放在k 中。这样看来,如果i 是一个寄存器变量或者表示一个端口数据或者是多个线程的共享数据,就容易出错,所以说volatile可以保证对特殊地址的稳定访问。*******************************************************************************************************************/

单线程环境下volatile与synchronized是否有必要

volatile的作用是: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。synchronized 是Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。 一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。三、当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。四、第三个例子同样适用其它同步代码块。当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

为什么在多核多线程程序中要慎用volatile关键字

a. 避免用通用寄存器对内存读写的优化。编译器常做的一种优化就是:把常用变量的频繁读写弄到通用寄存器中,最后不用的时候再存回内存中。但是如果某个内存地址中的值是由片外决定的(例如另一个线程或是另一个设备可能更改它),那就需要volatile关键字了。(感谢Kenny老师指正)b.硬件寄存器可能被其他设备改变的情况。例如一个嵌入式板子上的某个寄存器直接与一个测试仪器连在一起,这样在这个寄存器的值随时可能被那个测试仪器更改。在这种情况下如果把该值设为volatile属性的,那么编译器就会每次都直接从内存中去取这个值的最新值,而不是自作聪明的把这个值保留在缓存中而导致读不到最新的那个被其他设备写入的新值。c. 同一个物理内存地址M有两个不同的内存地址的情况。例如两个程序同时对同一个物理地址进行读写,那么编译器就不能假设这个地址只会有一个程序访问而做缓存优化,所以程序员在这种情况下也需要把它定义为volatile的。

java单例双重检查锁为什么需要加volatile关键字

volatile关键字起到提醒JVM这个变量永远去内存当中去获取值(有时候值会被写到寄存器当中)被volatile声明的变量,那么所有的线程都会得到一样的值。

关键字volatile,inline有什么用

volatile 是把变量标识为“变化中的”。意思是这个变量即使在(主线程)没有任何存取操作的情况下也可能在(被其他线程)变化。写上提醒注意线程安全。Java 1.4及之前版本加了这个的变量也没有同步安全。Java 5以后加了volatile后会在读取方面有同步安全。

加不加Volatile看不出有什么效果啊求解

想看出效果来比较困难!一个boolean 本省就是原子操作。如果你换一个真正的Object,n个线程操作,你就会发现有效果了。参见:以下为引用IBM网站上Java64 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量。这两种机制的提出都是为了实现代码线程的安全性。其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低),而且其使用也更容易出错。在这期的 Java 理论与实践 中,Brian Goetz 将介绍几种正确使用 volatile 变量的模式,并针对其适用性限制提出一些建议。Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。本文介绍了几种有效使用 volatile 变量的模式,并强调了几种不适合使用 volatile 变量的情形。锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility)。互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的 —— 如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前的值或不一致的值,这将引发许多严重问题。Volatile 变量Volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性。这就是说线程能够自动发现 volatile 变量的最新值。Volatile 变量可用于提供线程安全,但是只能应用于非常有限的一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。因此,单独使用 volatile 还不足以实现计数器、互斥锁或任何具有与多个变量相关的不变式(Invariants)的类(例如 “start <=end”)。出于简易性或可伸缩性的考虑,您可能倾向于使用 volatile 变量而不是锁。当使用 volatile 变量而非锁时,某些习惯用法(idiom)更加易于编码和阅读。此外,volatile 变量不会像锁那样造成线程阻塞,因此也很少造成可伸缩性问题。在某些情况下,如果读操作远远大于写操作,volatile 变量还可以提供优于锁的性能优势。正确使用 volatile 变量的条件您只能在有限的一些情形下使用 volatile 变量替代锁。要使 volatile 变量提供理想的线程安全,必须同时满足下面两个条件:对变量的写操作不依赖于当前值。该变量没有包含在具有其他变量的不变式中。实际上,这些条件表明,可以被写入 volatile 变量的这些有效值独立于任何程序的状态,包括变量的当前状态。第一个条件的限制使 volatile 变量不能用作线程安全计数器。虽然增量操作(x++)看上去类似一个单独操作,实际上它是一个由读取-修改-写入操作序列组成的组合操作,必须以原子方式执行,而 volatile 不能提供必须的原子特性。实现正确的操作需要使 x 的值在操作期间保持不变,而 volatile 变量无法实现这点。(然而,如果将值调整为只从单个线程写入,那么可以忽略第一个条件。)大多数编程情形都会与这两个条件的其中之一冲突,使得 volatile 变量不能像 synchronized 那样普遍适用于实现线程安全。清单 1 显示了一个非线程安全的数值范围类。它包含了一个不变式 —— 下界总是小于或等于上界。

java volatile变量为什么不能保证原子性

被volatile修饰的变量保证的是可见性,不是原子性。这是两个不同的概念。可见性是指不论在哪个线程中看,同一个对象同一时刻的值总是一样的,不会出现不一致的情况。原子性是指一个操作要么完成,要么没有完成,不会出现完成了一半的情况。

只读的状态寄存器.它是volatile因为它可能被意想不到地改变.它是const因为程序不应该试图去修改它.

程序不会去修改它 也不应该去修改它 对于你的程序来说 它是只读的但是volatile表明它可能被其他器件更改比如外部信号 或者其他类似的外部器件

volatile 引用哪个头文件

volatile是C语言里面的一个关键字,不需要引用。volatile是一个类型修饰符(type specifier),就像大家更熟悉的const一样,它是被设计用来修饰被不同线程访问和修改的变量,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。说人话,就是:变量可能会被意想不到地改变,添加volatile关键字后,每次使用这个变量,都会确保里面的值是最新的值。

是不是用了volatile的变量或指针等 后,都直接从内存中读取数据

没有错。volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。 有volatie修饰的变量,每次操作时遵循下面动作: 从内存取值 ---> 放入寄存器 ---> 操作 --->写回内存 没有volatie修饰的变量,操作可能遵循(可能的意思是:不是所有情况都如此): 从内存取值 ---> 放入寄存器 ---> 第一次操作 ---> 第二次操作(此时仍操作寄存器中的值) …… --->第N次操作 --->写回内存

volatile一般用来修饰结构体中的成员变量吗?

请参考:http://baike.baidu.com/view/608706.htm

java之用volatile和不用volatile的区别

在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。要解

java之用volatile和不用volatile的区别

volatile关键字是用来干什么的?当一个变量定义为 volatile 之后,将具备两种特性:  1.保证此变量对所有的线程的可见性,这里的“可见性”,如本文开头所述,当一个线程修改了这个变量的值,volatile 保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新。但普通变量做不到这点,普通变量的值在线程间传递均需要通过主内存(详见:Java内存模型)来完成。  2.禁止指令重排序优化。有volatile修饰的变量,赋值后多执行了一个“load addl $0x0, (%esp)”操作,这个操作相当于一个内存屏障(指令重排序时不能把后面的指令重排序到内存屏障之前的位置),只有一个CPU访问内存时,并不需要内存屏障;(什么是指令重排序:是指CPU采用了允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理)。volatile 性能:  volatile 的读性能消耗与普通变量几乎相同,但是写操作稍慢,因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。volatile 原理:  volatile变量,用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。  在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比sychronized关键字更轻量级的同步机制。  当对非 volatile 变量进行读写的时候,每个线程先从内存拷贝变量到CPU缓存中。如果计算机有多个CPU,每个线程可能在不同的CPU上被处理,这意味着每个线程可以拷贝到不同的 CPU cache 中。  而声明变量是 volatile 的,JVM 保证了每次读变量都从内存中读,跳过 CPU cache 这一步。

一个指针可以是volatile吗?解释下为什么

可以,具体你看看这个http://blog.21ic.com/user1/164/archives/2005/1271.html

static 和 Volatile 的区别

作者:David链接:https://www.zhihu.com/question/41579791/answer/91619879来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。static指的是类的静态成员,实例间共享volatile跟Java的内存模型有关,线程执行时会将变量从主内存加载到线程工作内存,建立一个副本,在某个时刻写回。valatile指的每次都读取主内存的值,有更新则立即写回主内存。理解了这两点,逐句再来解释你的困惑:“既然static保证了唯一性”:static保证唯一性,指的是static修饰的静态成员变量是唯一的,多个实例共享这唯一一个成员。“那么他对多个线程来说都是可见的啊”:这里,static其实跟线程没太大关系,应该说对多个对象实例是可见的。你说对多个线程可见,虽然没什么毛病,因为静态变量全局可见嘛,但是把这个理解转到线程的上线文中是困惑的起因。“volatile保证了线程之间的可见性”:因为线程看到volatile变量会去读取主内存最新的值,而不是自个一直在那跟内部的变量副本玩,所以保证了valatile变量在各个线程间的可见性。“那么修改的时候只要是原子操作,那么就会保证它的唯一性了吧”:此时你说的“唯一性”,指的是各个线程都能读取到唯一的最新的主内存变量,消除了线程工作内存加载变量副本可能带来的线程之间的“不唯一性”。这里“唯一性”的含义跟第一句说的“唯一性”是不一样的。“这两个在我理解上我觉得差不多。”:其实解决问题的“场景”是完全不一样的。

c代码中volatile关键字的作用,除了阻止cpu直接使用寄存器和cache中变量,还有其他功能吗?

volatile表明该变量可能在其它代码中被修改,以免编译器在优化时出现错误。比如以下程序:int x, y; x = 5; y = x + 1;只看这段代码,在编译优化时,完全可以把y = x + 1 直接编译成 y=6 而得到完全正确的结果。如果把x声明为 volatile int x; 编译器就不会做这种猜测性的优化,而直接使用x的现有值。声明为volatile,只有该变量在其它模块中可能被修改的情况下才有意义,否则只会阻止对该变量进行的编译优化,降低编译效率。对于auto类型、static类型的变量,显然没必要声明为volatile的。可以说,只有可能在其它模块中被修改的全局符号,只有在编写并发程序时,才可能出现使用volatile的必要性。

volatile关键字和原子操作的区别

fuck,这两者不是并列关系,说不上区别。先说一下,本人水平有限,说错了的话请方家包涵。volatile关键字和sychronized一样,作用都是为了多线程同步的。不同的是volatile是确保了多线程中原子操作的可见性,就是说你在一个线程中进行原子操作,另一个线程是可以看到之前原子操作的结果的。而sychronized应用更广泛,范围也扩展到你想要同步的代码块,也更不容易出问题。原子操作就是线程相关的单步操作,不能分割的操作,其‘不可分割"的现实体现是:在共享内存中的变量,你可以不用sychronized去修饰,而只使用volatile关键字去修饰这个变量,就可以做到可见性。如果对它的操作不是原子操作,那么volatile也就不能确保线程同步了。而复杂的操作则应该使用sychronized,而线程同步中,使用volatile效率比sychronized高不少,但也很容易出问题,基本上建议尽可能使用sychronized。

为什么不用volatile关键字声明的变量,却能

volatile 用于编译器编译时,它告诉编译器,“编译时不要对我作优化,我的数值会嵌套变化的,你不一定懂,别优化噢!”片段程序例子: int some_int = 100;while(some_int == 100){ 循环体程序块 };变量声明未用volatile,编译时会优化成 while(true){ 循环体程序块 };用了 volatile int some_int = 100; 就会保持 while(some_int == 100)....

volatile应用在什么场景

volatile有五个使用场景:1.作为状态标志2.一次性安全发布3.独立观察4.volatile bean模式5.开销较低的读写锁策略

volatile*转普通指针要什么?

C语言里只能强转:volatile int* vp;int* p = (int*)(vp);C++里可以用const_cast,不要被const_cast的名称迷惑了,const_cast不仅可以去掉const限定,也可以去掉volatile限定:volatile int* vp;int* p = const_cast<int*>(vp);

为什么在多线程程序中要慎用volatile关键字

  因为volatile并不能保证其原子性,他只保证了某一个线程对他修改以后其他线程可见,  尤其是当多个线程对一个变量自增活自减时会导致变量出错。  参照《深入理解java虚拟机》一书,volatile运用在以下场景:  1>运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。  2>变量不需要与其他的状态变量共同参与不变约束(表示看不懂这句)。  因此,在使用volatile关键字时要慎重,并不是只要简单类型变量使用volatile修饰,对这个变量的所有操作都是原来操作,当变量的值由自身的 上一个决定时,如n=n+1、n++等,volatile关键字将失效,只有当变量的值和自身上一个值无关时对该变量的操作才是原子级别的,如n = m+1,这个就是原级别的。所以在使用volatile关键时一定要谨慎,如果自己没有把握,可以使用synchronized来代替volatile。

c 语言中关于 volatile 形参问题??

会的,因为加上volatile限定符就表示他可能会被意外改变,优化器每次都会直接读他的值

volatile acidity是什么啊?

挥发性酸

C/C++ 中volatile 为什么不能保障原子性,或者什么情况下能保障原子性,分不多,第一个问题

退热贴

一个指针可以使volatile吗

当然可以。volatile 修饰指针,一般用在共享指针上面。即这个指针是被其它代码共享的,经常变化的,这时候,加上 volatile 关键字,可以防止被编译器优化。

什么情况下volatile的值会被改变

你这是单线程的程序,变量值永远不会改变。除非改写成多线程。http://baike.baidu.com/view/608706.htm

用C++进行多线程有没有必要加volatile么?

可以说volatile这个关键字并不是多线程专有的,很多嵌入式开发里都会有。主要控制的就是当修改变量时系统仅是改了临时存放变量的寄存器而没有及时更改相应内存,这会导致这段空窗期的其他程序读取这个内存数据时是过时的,或者说就是错误的。很多嵌入式开发中,都会有这样的问题,外部IO口的变化会使系统内部某变量改变,但是不用这个关键字可能会导致非常严重的控制错误。比如电梯运行中的平层信号,如果没有及时写入内存,将会使系统读取一个错误的楼层数据,结果是灾难性的。多线程中,这个关键字的作用类同,都是出于同步控制的考量。总之volatile和多线程没有关系volatile和多线程没有关系volatile和多线程没有关系,重要的事情说三遍。加了volatile不会让错误的程序变正确,去掉volatile也不会让正确的程序变错误。如果你愿意大可以加上这个东西,反正它除了让你的程序变慢一点之外不会有其它影响。

static 和 Volatile 的区别

static是静态的,volatile是易失的。随机访问存储器里的数据就是volatile的,而只读存储器里的数据就是static的。内存是电脑的记忆部件,用于存放电脑运行中的原始数据、中间结果以及指示电脑工作的程序。内存可以分为随机访问存储器和只读存储器,前者允许数据的读取与写入,磁盘中的程序必须被调入内存后才能运行,中央处理器可直接访问内存,与内存交换数据。电脑断电后,随机访问存储器里的信息就会丢失,这种数据就叫做volatile data,后者的信息只能读出,不能随意写入,即使断电也不会丢失,这种数据叫做static data。

static 和 Volatile 的区别

1.volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果不加入volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。2.volatile的作用是: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值.3.C++与C#的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用.static作用:static静态变量声明符。在声明它的程序块,子程序块或函数内部有效,值保持,在整个程序期间分配存储器空间,编译器默认值0。

static 和 Volatile 的区别

static:静态类型。在面向过程编程中,限制了变量和函数的作用域及存储域;在面向对象编程中,静态数据和函数为所有对象共有,只开辟一个存储区。 volatile:通常用于直接与硬件打交道的场合,它们的值可由程序以外的过程控制,比如硬件寄存器。

const和volatile的区别

const 指定了我们的程序代码中是不可以改变这个变量的,但是我们不能保证,由于硬件的原因,导致这个值被改变。volatile 关键字表示,编译器进行强制 I/O 寻址,而非读取寄存器的值。一般情况下,连续使用的变量,编译器会先把数据读出来,并且保存到寄存器里,使用的时候,直接读取寄存器里的数据,这样处理速度会快一点,但是,有些时候,比如实时读取按键值,或者其它要求比较实时的数据,就不能使用寄存器了,必须要用到 volatile 关键字了。所以然,有些时候,const 和 volatile 是可以配合使用的。

c/c++ volatile关键字个人总结

最近有同事提到了volatile关键字,所以感兴趣就上网去学习了下,但是在网上看的云里雾里的,因为很多帖子都是明确说明volatile的定义了,然后就各种给你讲例子它应该如何应用到多线程中使用,我个人也写了例子,程序运行没有实现出他们多线程的效果。不过看了很多帖子也花费了很多时间,就做一个总结吧。 1:volatile的历史 volatile诞生于单cpu核心时代,为保持兼容,一直只是针对编译器的,对cpu无影响。 2:volatile在c/c++中的作用: 1.告诉编译器不要将定义的变量优化掉。 2.告诉编译器总是从缓存取被修饰的变量值,而不是寄存器取值。 注释:volatile针对的编译器。很多帖子上升到内存屏障,保证执行乱序的高度了,你们帮忙吹牛逼不犯法么? 3:volatile的应用场景: (1)信号处理程序。 (2)与硬件打交道(嵌入式开发) (3)setjmp和longjmp(函数间跳转关键字) 注释:如果你搞嵌入式程序开发可以更多的关注一下,如果不是,没有必要过多关注。他不会在多线程上对程序起到多么牛逼的好处,起码我自己写程序没有。我的电脑是两核的。不高,难道用8核的会有不一样的效果?

static volatile a b=c;

static和volatile都是修饰符,static是静态局部变量,volatile是用来修饰被不同线程访问和修改的变量用法一两句说不清,我给你两个链接:http://baike.baidu.com/link?url=Vtirr6oOHv87wlExhO_YxiLzjpq8pCP5ZQuJVa3qRjpMmFEzYDOww6CNQfsuFwwGhttp://baike.baidu.com/link?url=V1e9gY-AyTTxQ2rYHHpKwNarJ22ClGyzsNZOYlbzMifgYsJgm2QSwl-xhbS8wHahstatic volatile a b=c;中a是类型,和int差不多,b是变量名,c是值int c=2;static volatile int b=c;这样就清楚了

volatile关键字是否能保证线程安全

volatile不是保护线程安全的。它保护的是变量安全。主要的功能是保护变量不被主函数和中断函数反复修改造成读写错误。

java中对象或者数组用volatile修饰有什么用

就像大家更熟悉的const一样,volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会volatile的作用是: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值.

static 和 Volatile 的区别

static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。就象大家更熟悉的const一样,volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。下面我们来一个个说明。考虑下面的代码:代码:class Gadget{public:void Wait(){while (!flag_){Sleep(1000); // sleeps for 1000 milliseconds}}void Wakeup(){flag_ = true;}...private:bool flag_;};

Volatile修饰数组有意义吗

Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。

static 和 Volatile 的区别

变量放在主存区上,使用该变量的每个线程,都将从主存区拷贝一份到自己的工作区上进行操作。volatile, 声明这个字段易变(可能被多个线程使用),Java内存模型负责各个线程的工作区与主存区的该字段的值保持同步,即一致性。static, 声明这个字段是静态的(可能被多个实例共享),在主存区上该类的所有实例的该字段为同一个变量,即唯一性。volatile, 声明变量值的一致性;static,声明变量的唯一性。此外,volatile同步机制不同于synchronized, 前者是内存同步,后者不仅包含内存同步(一致性),且保证线程互斥(互斥性)。static 只是声明变量在主存上的唯一性,不能保证工作区与主存区变量值的一致性;除非变量的值是不可变的,即再加上final的修饰符,否则static声明的变量,不是线程安全的。下面摘自Java语言规范(Java Language Specification)的官方解释:1) If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. 2) A field may be declared volatile, in which case the Java Memory Model ensures that all threads see a consistent value for the variable。

java中对象或者数组用volatile修饰有什么用?

http://zhidao.baidu.com/question/331268847.html

JAVA 里static 和volatile的区别

static是静态的声明,volatile是重新配置

关键字static、Const、Volatile的作用是什么

在C语言中,关键字static有三个明显的作用:1). 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。2). 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。3). 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。大多数应试者能正确回答第一部分,一部分能正确回答第二部分,同是很少的人能懂得第三部分。这是一个应试者的严重的缺点,因为他显然不懂得本地化数据和代码范围的好处和重要性。我只要一听到被面试者说:“const意味着常数”,我就知道我正在和一个业余者打交道。去年Dan Saks已经在他的文章里完全概括了const的所有用法,因此ESP(译者:Embedded Systems Programming)的每一位读者应该非常熟悉const能做什么和不能做什么.如果你从没有读到那篇文章,只要能说出const意味着“只读”就可以了。尽管这个答案不是完全的答案,但我接受它作为一个正确的答案。(如果你想知道更详细的答案,仔细读一下Saks的文章吧。)如果应试者能正确回答这个问题,我将问他一个附加的问题:下面的声明都是什么意思?const int a;int const a;const int *a;int * const a;int const * a const;前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。如果应试者能正确回答这些问题,那么他就给我留下了一个好印象。顺带提一句,也许你可能会问,即使不用关键字 const,也还是能很容易写出功能正确的程序,那么我为什么还要如此看重关键字const呢?我也如下的几下理由:2). 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。3). 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:1). 并行设备的硬件寄存器(如:状态寄存器)2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)3). 多线程应用中被几个任务共享的变量假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。int square(volatile int *ptr){return *ptr * *ptr;}下面是答案:1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:int square(volatile int *ptr){int a,b;a = *ptr;b = *ptr;return a * b;}由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

关键字volatile有什么含义?并给出三个不同的例子

volatile 是说这变量可能会被意想不到地改变通俗的解释下(不知道确切不):你要喝豆浆,豆浆通常是做好放在杯子里,通常情况下你只要端起杯子喝就可以达到目的,但是,有一天杯子里放的是奶茶,你拿起杯子就不可能喝道豆浆也就是说,你要喝豆浆,就要去找豆浆,而不能看杯子volatile 的意思可以理解成 从原始地址取值

JAVA 里static 和volatile的区别

变量放在主存区上,使用该变量的每个线程,都将从主存区拷贝一份到自己的工作区上进行操作。volatile, 声明这个字段易变(可能被多个线程使用),Java内存模型负责各个线程的工作区与主存区的该字段的值保持同步,即一致性。static, 声明这个字段是静态的(可能被多个实例共享),在主存区上该类的所有实例的该字段为同一个变量,即唯一性。volatile, 声明变量值的一致性;static,声明变量的唯一性。此外,volatile同步机制不同于synchronized, 前者是内存同步,后者不仅包含内存同步(一致性),且保证线程互斥(互斥性)。static 只是声明变量在主存上的唯一性,不能保证工作区与主存区变量值的一致性;除非变量的值是不可变的,即再加上final的修饰符,否则static声明的变量,不是线程安全的。下面摘自Java语言规范(Java Language Specification)的官方解释:1) If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. 2) A field may be declared volatile, in which case the Java Memory Model ensures that all threads see a consistent value for the variable。

关于c语言中的volatile限定符

本章描述C++的表达式,表达式是用于一个或多个以下目的的运算符和操作数序列:* 从操作数计算出一个值* 设计对象或函数* 产生“副作用”(副作用是非表达式求值的任何动作,例如,修改一个对象的值)。在C++中,运算符可被重载而且它们的含义可由用户定义,但是它们的优先级以及所带操作数的个数不能被修改。本章描述该语言中所提供的而非重载的运算符的语法和语义,包括以下主题:* 表达式的类型* 表达式的语义* 造型转换(有关重载的运算符的更多信息参见第12章“重载”中的“重载的运算符”)。注意:内部类型的运算符不能被重载,它们的行为是预先定义好的。

static 和 Volatile 的区别

变量放在主存区上,使用该变量的每个线程,都将从主存区拷贝一份到自己的工作区上进行操作。volatile, 声明这个字段易变(可能被多个线程使用),Java内存模型负责各个线程的工作区与主存区的该字段的值保持同步,即一致性。static, 声明这个字段是静态的(可能被多个实例共享),在主存区上该类的所有实例的该字段为同一个变量,即唯一性。volatile, 声明变量值的一致性;static,声明变量的唯一性。此外,volatile同步机制不同于synchronized, 前者是内存同步,后者不仅包含内存同步(一致性),且保证线程互斥(互斥性)。static 只是声明变量在主存上的唯一性,不能保证工作区与主存区变量值的一致性;除非变量的值是不可变的,即再加上final的修饰符,否则static声明的变量,不是线程安全的。下面摘自Java语言规范(Java Language Specification)的官方解释:1) If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. 2) A field may be declared volatile, in which case the Java Memory Model ensures that all threads see a consistent value for the variable。

volatile和lock的区别

volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果不加入volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。volatile的作用是: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值.C++与C#的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用.static作用:static静态变量声明符。在声明它的程序块,子程序块或函数内部有效,值保持,在整个程序期间分配存储器空间,编译器默认值0。

java 里面volatile什么意思啊

Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。 就跟C中的一样 禁止编译器进行优化~~~~

关键字volatile有什么含意?并给出三个不同的例子

精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。 下面是volatile变量的几个例子: 1). 并行设备的硬件寄存器(如:状态寄存器) 2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 3). 多线程应用中被几个任务共享的变量 回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。 假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。 int square(volatile int *ptr) { return *ptr * *ptr;}下面是答案: 1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。 2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。 3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码: int square(volatile int *ptr) {int a,b;a = *ptr;b = *ptr;return a * b;}由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值! 正确的代码如下: long square(volatile int *ptr) {int a;a = *ptr;return a * a;}Volatile 关键字告诉编译器不要持有变量的临时性拷贝。一般用在多线程程序中,以避免在其中一个线程操作该变量时,将其拷贝入寄存器。 请看以下情形: A线程将变量复制入寄存器,然后进入循环,反复检测寄存器的值是否满足一定条件(它期待B线程改变变量的值。 在此种情况下,当B线程改变了变量的值时,已改变的值对其在寄存器的值没有影响。所以A线程进入死循环。

java 里 volatile 关键字有什么特性 是否能保证线程安全

Java语言中关键字 volatile 被称作轻量级的 synchronized,与synchronized相比,volatile编码相对简单且运行的时的开销较少,但能够正确合理的应用好 volatile 并不是那么的容易,因为它比使用锁更容易出错,接下来本文主要介绍 volatile 的使用准则,以及使用过程中需注意的地方。为何使用volatile?(1)简易性:在某些需要同步的场景下使用volatile变量要比使用锁更加简单(2)性能:在某些情况下使用volatile同步机制的性能要优于锁(3)volatile操作不会像锁一样容易造成阻塞volatile特性(1)volatile 变量具有 synchronized 的可见性特性,及如果一个字段被声明为volatile,java线程内存模型确保所有的线程看到这个变量的值是一致的(2)禁止进行指令重排序(3)不保证原子性注:① 重排序:重排序通常是编译器或运行时环境为了优化程序性能而采取的对指令进行重新排序执行的一种手段② 原子性:不可中断的一个或一系列操作③ 可见性:锁提供了两种主要特性:互斥和可见性,互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的。volatile的实现原理如果对声明了volatile的变量进行写操作,JVM就会向处理器发送一条Lock前缀的指令,该Lock指令会使这个变量所在缓存行的数据回写到系统内存,根据缓存一致性协议,每个处理器都会通过嗅探在总线上传输的数据来检查自己缓存的值是否已过期,当处理器发现自己的缓存行对应的地址被修改,就会将当前处理器的缓存行设置成无效状态,在下次访问相同内存地址时,强制执行缓存行填充。正确使用volatile的场景volatile 主要用来解决多线程环境中内存不可见问题。对于一写多读,是可以解决变量同步问题,但是如果多写,就无法解决线程安全问题。如:1、不适合使用volatile的场景(非原子性操作)(1)反例private static volatile int nextSerialNum = 0;public static long generateSerialNum() {return nextSerialNum++;}这个方法的目的是要确保每次调用都返回不同的自增值,然而结果并不理想,问题在于增量操作符(++)不是原子操作,实际上它是一个由读取-修改-写入操作序列组成的组合操作,如果第二个线程在第一个线程读取旧值和写回新值期间读取这个域,第二个线程与第一个线程就会读取到同一个值。(2)正例其实面对上面的反例场景可以使用JDK1.5 java.util.concurrent.atomic中提供的原子包装类型来保证原子性操作private static AtomicInteger nextSerialNum = new AtomicInteger(0);public static long generateSerialNum() {return nextSerialNum.getAndIncrement();}2、适合使用volatile的场景在日常工作当中volatile大多被在状态标志的场景当中,如:要通过一个线程来终止另外一个线程的场景(1)反例private static boolean stopThread;public static void main(String[] args) throws InterruptedException {Thread th = new Thread(new Runnable() {@Overridepublic void run() {int i = 0;while (!stopThread) {i++;}}});th.start();TimeUnit.SECONDS.sleep(2);stopThread = true;}运行后发现该程序根本无法终止循环,原因是,java语言规范并不保证一个线程写入的值对另外一个线程是可见的,所以即使主线程main函数修改了共享变量stopThread状态,但是对th线程并不一定可见,最终导致循环无法终止。(2)正例private static volatile boolean stopThread;public static void main(String[] args) throws InterruptedException {Thread th = new Thread(new Runnable() {@Overridepublic void run() {int i = 0;while (!stopThread) {i++;}}});th.start();TimeUnit.SECONDS.sleep(2);stopThread = true;}通过使用关键字volatile修饰共享变量stopThread,根据volatile的可见性原则可以保证主线程main函数修改了共享变量stopThread状态后对线程th来说是立即可见的,所以在两秒内线程th将停止循环。

C语言中的volatile是什么意思?怎么用?谢了

C语言关键字volatile,表示不经过赋值,其值也可能被改变

java里面volatile是什么意思?

Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。 就跟C中的一样 禁止编译器进行优化~~~~

java的volatile是什么意思

一般的,如果多个线程协作存、取某个变量时,一般需要用到synchronized关键字进行同步操作,如:public class MyTestThread extends MyTest implements Runnable { private boolean _done = false; public synchronized boolean getDone() { return _done; } public synchronized void setDone(boolean b) { _done = b; } public void run( ) { boolean done; done = getDone(); while (!done) { repaint( ); try { Thread.sleep(100); } catch (InterruptedException ie) { return; } } }}或者:public class MyTestThread extends MyTest implements Runnable { private boolean _done = false; public void setDone(boolean b) { synchronized(this) { _done = b; } } public void run( ) { boolean done; synchronized(this) { done = _done; } while (!done) { repaint( ); try { Thread.sleep(100); } catch (InterruptedException ie) { return; } } }}但是,通过volatile关键字,我们可以大大简化:public class MyTestThread extends MyTest implements Runnable { private volatile boolean done = false; public void run( ) { while (!done) { repaint( ); try { Thread.sleep(100); } catch (InterruptedException ie) { return; } } } public void setDone(boolean b) { done = b; }}

volatile关键字的作用是什么?

volatile是一个特征修饰符(type specifier).volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。与锁相比,Volatile变量是一种非常简单但同时又非常脆弱的同步机制,它在某些情况下将提供优于锁的性能和伸缩性。扩展资料:使用地方一般说来,volatile用在如下的几个地方:1、中断服务程序中修改的供其它程序检测的变量需要加volatile;2、多任务环境下各任务间共享的标志应该加volatile;3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能有不同意义;另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2 中可以禁止任务调度,3中则只能依靠硬件的良好设计了。

为什么 long 和double 加上volatile

volatile变量主要用在以下几个方面:(1)并行设备的硬件寄存器(如状态寄存器);(2)一个中断服务子程序中会访问到的非自动变量;(3)多线程应用中被几个任务共享的变量

多线程编程中什么情况下需要加 volatile

C/C++多线程编程中不要使用volatile。(注:这里的意思指的是指望volatile解决多线程竞争问题是有很大风险的,除非所用的环境系统不可靠才会为了保险加上volatile,或者是从极限效率考虑来实现很底层的接口。这要求编写者对程序逻辑走向很清楚才行,不然就会出错)C++11标准中明确指出解决多线程的数据竞争问题应该使用原子操作或者互斥锁。C和C++中的volatile并不是用来解决多线程竞争问题的,而是用来修饰一些因为程序不可控因素导致变化的变量,比如访问底层硬件设备的变量,以提醒编译器不要对该变量的访问擅自进行优化。简单的来说,对访问共享数据的代码块加锁,已经足够保证数据访问的同步性,再加volatile完全是多此一举。如果光对共享变量使用volatile修饰而在可能存在竞争的操作中不加锁或使用原子操作对解决多线程竞争没有任何卵用,因为volatile并不能保证操作的原子性,在读取、写入变量的过程中仍然可能被其他线程打断导致意外结果发生。

请问在 C 语言中const与volatile是什么意思?

const 常量,运行时不可改变volatile 编译器不要优化(多用于寄存器)

JAVA 里static 和volatile的区别

区别如下:1)static是类变量,是所有类的对象都可以共享的;在多线程里,假设有两个线程t1,t2,t1对其本地缓存中的静态变量进行的更新不会反映在t2缓存的静态变量中 ,2)volatile是实例变量,每个实例都有着自己的副本。在多线程里,假设有两个线程t1,t2,t1,t2同时访问同一个对象并更新一个被声明为volatile的变量,t1,t2缓存中的volatile变量将只有一个主副本,它将被不同的线程更新,并且由一个线程对volatile变量进行的更新将立即反映到另一个线程。

c语言什么时候用volatile

当一个对象的值可能会在编译器的控制或检测之外被改变时,例如一个被系统时钟更新的变量,那么对象应该声明成volatile。编译器执行的某些例行优化行为不能应用在已指定为volatile的对象上。volatile限定符的用法同const非常相似,都是作为类型的附加修饰符。volatile修饰符的主要目的是提示编译器,该对象的值可能在编译器未监测到的情况下被改变。因此编译器不能武断的对引用这些对象的代码作优化处理。

C++中volatile对象怎么用?她有什么注意事项吗?

volatile的语法和const的是一样的,但是volatile的意思是“在编译器认识的范围外,这个数据可以改变”。环境正在改变数据(可能通过多任务、多线程或者中断处理),所以,volatile告诉编译器不要擅自做出有关该数据的任何假定,优化期间尤其如此。 如果编译器说:“我已经把数据读进寄存器,而且再没有与寄存器接触”。一般情况下,它不需要再读这些数据。但是,如果数据是volatile修饰的,编译器就不能做出这样的假定,因为这个数据可能被其他进程改变了,它必须重读这个数据而不是优化这个代码来消除通常情况下那些冗余的读操作代码。 volatile的语法与const是一样的,为指明可以选择两个中的任何一个,把他们连在一起统称为c-v限定词(c-v qualifier)。我C++笔记里的,希望对你有用,讨论请发邮件incubus.w@163.com.

volatile 可以用来修饰函数返回值吗

不可以

C语言 中volatile关键字的用法

一个参数既可以是const又可以是volatile吗

当然可以。举个例子,就是只读的状态寄存器。const 指定了我们的程序代码中是不可以改变这个变量的,但是我们不能保证,由于硬件的原因,在代码外更改这个值,volatile表示我们的代码同时会更新使用这个最新的数值。

哪些变量需要加volatile

一般情况下,连续使用的变量,编译器会先把数据读出来,并且保存到寄存器里,使用的时候,直接读取寄存器里的数据,这样处理速度会快一点,但是,有些时候,比如实时读取按键值,或者其它要求比较实时的数据,就不能使用寄存器了,必须要用到 volatile 关键字了。因为 volatile 关键字指示编译器进行强制 I/O 寻址,而非读取寄存器的值。

为什么在多核多线程程序中要慎用volatile关键字

1、避免用通用寄存器对内存读写的优化。编译器常做的一种优化就是:把常用变量的频繁读写弄到通用寄存器中,最后不用的时候再存回内存中。但是如果某个内存地址中的值是由片外决定的(例如另一个线程或是另一个设备可能更改它),那就需要volatile关键字了。(感谢Kenny老师指正)2、硬件寄存器可能被其他设备改变的情况。例如一个嵌入式板子上的某个寄存器直接与一个测试仪器连在一起,这样在这个寄存器的值随时可能被那个测试仪器更改。在这种情况下如果把该值设为volatile属性的,那么编译器就会每次都直接从内存中去取这个值的最新值,而不是自作聪明的把这个值保留在缓存中而导致读不到最新的那个被其他设备写入的新值。3、同一个物理内存地址M有两个不同的内存地址的情况。例如两个程序同时对同一个物理地址进行读写,那么编译器就不能假设这个地址只会有一个程序访问而做缓存优化,所以程序员在这种情况下也需要把它定义为volatile的。

static 和 Volatile 的区别

static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。就象大家更熟悉的const一样,volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。下面我们来一个个说明。考虑下面的代码:代码:class Gadget{public:void Wait(){while (!flag_){Sleep(1000); // sleeps for 1000 milliseconds}}void Wakeup(){flag_ = true;}...private:bool flag_;};

C语言中volatile在什么情况下使用

简单的理解就是这个变量可能会被外部函数改变,为了让这个改变能有效执行,不被编译器优化掉。举个例子吧,一个函数用了一个外部的变量,但这个变量在此函数中没有改变,只是引用,这时候编译器会去做优化,把它的值暂放在内部寄存器中,用的时候读取的是寄存器的值,而不是去访问它的地址取值,这样的话,当这个变量在外部发生了变化的时候,比如中断,或者另外的进程等等。但在这个函数里面就不能起作用,因为被优化后使用的是寄存器的值,还是原来的值,导致错误发生。这种情况下,就要加上这个定义,就不会被优化了。

static和volatile有哪些用途用途。

static是静态获取,volatile是从列表中获取

static 和 Volatile 的区别

static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。就象大家更熟悉的const一样,volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。下面我们来一个个说明。考虑下面的代码:代码:class Gadget{public:void Wait(){while (!flag_){Sleep(1000); // sleeps for 1000 milliseconds}}void Wakeup(){flag_ = true;}...private:bool flag_;};

static 和 Volatile 的区别

volatile, 声明这个字段易变(可能被多个线程使用),Java内存模型负责各个线程的工作区与主存区的该字段的值保持同步,即一致性。static, 声明这个字段是静态的(可能被多个实例共享),在主存区上该类的所有实例的该字段为同一个变量,即唯一性。volatile, 声明变量值的一致性;static,声明变量的唯一性。此外,volatile同步机制不同于synchronized, 前者是内存同步,后者不仅包含内存同步(一致性),且保证线程互斥(互斥性)。static 只是声明变量在主存上的唯一性,不能保证工作区与主存区变量值的一致性;除非变量的值是不可变的,即再加上final的修饰符,否则static声明的变量,不是线程安全的。

c语言中volatile关键字是什么含义

volatile 影响编译器编译的结果,指出,volatile 变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以免出错,(VC++ 在产生release版可执行码时会进行编译优化,加volatile关键字的变量有关的运算,将不进行编译优化。)。例如:volatile int i=10;int j = i;...int k = i;volatile 告诉编译器i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的可执行码会重新从i的地址读取数据放在k中。而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在k中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问,不会出错。

关键字volatile有什么含意?并给出三个不同的例子

精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。 下面是volatile变量的几个例子: 1). 并行设备的硬件寄存器(如:状态寄存器) 2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 3). 多线程应用中被几个任务共享的变量 回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。 假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。 int square(volatile int *ptr) { return *ptr * *ptr;}下面是答案: 1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。 2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。 3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码: int square(volatile int *ptr) {int a,b;a = *ptr;b = *ptr;return a * b;}由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值! 正确的代码如下: long square(volatile int *ptr) {int a;a = *ptr;return a * a;}Volatile 关键字告诉编译器不要持有变量的临时性拷贝。一般用在多线程程序中,以避免在其中一个线程操作该变量时,将其拷贝入寄存器。 请看以下情形: A线程将变量复制入寄存器,然后进入循环,反复检测寄存器的值是否满足一定条件(它期待B线程改变变量的值。 在此种情况下,当B线程改变了变量的值时,已改变的值对其在寄存器的值没有影响。所以A线程进入死循环。

C语言中的volatile是什么意思

volatile 实例讲解volatile的本意是一般有两种说法--1.“暂态的”;2.“易变的”。这两种说法都有可行。但是究竟volatile是什么意思,现举例说明(以Keil-c与a51为例例子来自Keil FQA),看完例子后你应该明白volatile的意思了,如果还不明白,那只好再看一遍了。例1.void main (void){volatile int i;int j;i = 1; //1 不被优化 i=1i = 2; //2 不被优化 i=1i = 3; //3 不被优化 i=1j = 1; //4 被优化j = 2; //5 被优化j = 3; //6 j = 3}---------------------------------------------------------------------例2.函数:void func (void){unsigned char xdata xdata_junk;unsigned char xdata *p = &xdata_junk;unsigned char t1, t2;t1 = *p;t2 = *p;}编译的汇编为:0000 7E00 R MOV R6,#HIGH xdata_junk0002 7F00 R MOV R7,#LOW xdata_junk;---- Variable "p" assigned to Register "R6/R7" ----0004 8F82 MOV DPL,R70006 8E83 MOV DPH,R6;!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 注意0008 E0 MOVX A,@DPTR0009 F500 R MOV t1,A000B F500 R MOV t2,A;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!000D 22 RET 将函数变为:void func (void){volatile unsigned char xdata xdata_junk;volatile unsigned char xdata *p = &xdata_junk;unsigned char t1, t2;t1 = *p;t2 = *p;}编译的汇编为:0000 7E00 R MOV R6,#HIGH xdata_junk0002 7F00 R MOV R7,#LOW xdata_junk;---- Variable "p" assigned to Register "R6/R7" ----0004 8F82 MOV DPL,R70006 8E83 MOV DPH,R6;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!0008 E0 MOVX A,@DPTR0009 F500 R MOV t1,A a处000B E0 MOVX A,@DPTR000C F500 R MOV t2,A;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!000E 22 RET 比较结果可以看出来,未用volatile关键字时,只从*p所指的地址读一次如在a处*p的内容有变化,则t2得到的则不是真正*p的内容。---------------------------------------------------------------------例3volatile unsigned char bdata var; // use volatile keyword heresbit var_0 = var^0;sbit var_1 = var^1;unsigned char xdata values[10];void main (void) { unsigned char i; for (i = 0; i < sizeof (values); i++) { var = values[i]; if (var_0) { var_1 = 1; //a处 values[i] = var; // without the volatile keyword, the compiler // assumes that "var" is unmodified and does not // reload the variable content. } }}在此例中,如在a处到下一句运行前,var如有变化则不会,如var=0xff; 则在values[i] = var;得到的还是values[i] = 1;---------------------------------------------------------------------应用举例:例1.#define DBYTE ((unsigned char volatile data *) 0)说明:此处不用volatile关键字,可能得不到真正的内容。---------------------------------------------------------------------例2.#define TEST_VOLATILE_C //***************************************************************// verwendete Include Dateien//***************************************************************#if __C51__ < 600 #error: !! Keil 版本不正确#endif//***************************************************************// 函数 void v_IntOccured(void)//***************************************************************extern void v_IntOccured(void);//***************************************************************// 变量定义//***************************************************************char xdata cvalue1; //全局xdatachar volatile xdata cvalue2; //全局xdata//***************************************************************// 函数: v_ExtInt0()// 版本:// 参数:// 用途:cvalue1++,cvalue2++//***************************************************************void v_ExtInt0(void) interrupt 0 { cvalue1++; cvalue2++; } //***************************************************************// 函数: main()// 版本:// 参数:// 用途:测试volatile//***************************************************************void main() {char cErg;//1. 使cErg=cvalue1;cErg = cvalue1;//2. 在此处仿真时手动产生中断INT0,使cvalue1++; cvalue2++if (cvalue1 != cErg) v_IntOccured();//3. 使cErg=cvalue2;cErg = cvalue2;//4. 在此处仿真时手动产生中断INT0,使cvalue1++; cvalue2++if (cvalue2 != cErg) v_IntOccured(); //5. 完成 while (1);}//***************************************************************// 函数: v_IntOccured()// 版本:// 参数:// 用途: 死循环//***************************************************************void v_IntOccured() { while(1);}仿真可以看出,在没有用volatile时,即2处,程序不能进入v_IntOccured();但在4处可以进入v_IntOccured();

volatile类型变量有什么特点

就象大家更熟悉的const一样,volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。参考:http://baike.baidu.com/view/608706.htm

定义为volatile的变量有什么作用

保留字肯定就是关键字撒, (1)auto 这个这个关键字用于声明变量的生存期为自动,即将不在任何类、结构、枚举、联合和函数中定义的变量视为全局变量,

如何理解volatile和const

volatile可理解为“编译器警告指示字”volatile用于告诉编译器必须每次去内存中取变量值volatile主要修饰可能被多个线程访问的变量volatile也可以修饰可能被未知因数更改的变量const和volatile放在一起的意义在于:(1)本程序段中不能对a作修改,任何修改都是非法的,或者至少是粗心,编译器应该报错,防止这种粗心;(2)另一个程序段则完全有可能修改,因此编译器最好不要做太激进的优化。“const”含义是“请做为常量使用”,而并非“放心吧,那肯定是个常量”。“volatile”的含义是“请不要做没谱的优化,这个值可能变掉的”,而并非“你可以修改这个值”。因此,它们本来就不是矛盾的。const修饰的变量不允许这里修改不代表不允许别处修改,比如:int i = 5;const int* p = &i;*p= 6; // 不可以;i = 7; // 完全可以,而且那个“const”的“*p”也跟着变成了7。对于非指针非引用的变量,const volatile同时修饰的意义确实不大。个人觉得。需要明白“volatile”的含义并非是“non-const”。所以他们才可以放在一起。在C++语言中,const没有反义词,如果一个变量没有const修饰,那它本身就是const的反义词,而并非加上volatile才是const的反义词。

java编程,如何彻底理解volatile关键字?

volatile在Java语言中扮演者重要的角色,它具有可见性以及禁止指令重排序两个非常显著的特点,要想解释清楚volatile的用法,首先我们要对Java的内存模型JMM有一个非常熟悉的了解,所以我从以下几点来分析volatile。Java的内存模型规定:所有的变量都保存在主内存中,每一个线程都有属于自己的工作内存,当读取主内存的变量时,线程的工作内存都会都会存储这个变量的副本,线程对变量的操作都是在自己的工作内存中,在适当的时候会把自己工作内存的变量同步到主内存中。从上面的内容中可以得出一个结论,多线程对变量的修改,都是先修改自己的工作内存的变量,然后把工作内存中修改的在适当的时候同步到主内存中,那么问题就来了,适当的时候是什么时候呢?不确定,所以就有问题了,当主内存中有一个变量i=0,假如同时有两个线程去修改i的值,当线程1读取主内存中的i=1,然后拷贝一份副本在自己的工作内存中,然后i=1,但是这是操作的自己的工作内存i=1,但是这个i=1什么时候刷新到主内存中呢?刚才我们说了,不确定,此时线程二读取主存的变量i=0,然后也拷贝一份到自己的工作内存中,然后i=2,然后在适当的时候刷新到主存中,所以最终的结果可能是线程二i=2的结果先刷新到主存中,线程一i=1最后刷新到主存中,这就导致现在主存中i=1,所以与想象的结果不一样。了解了Java的内存模型JMM,我们了解了对于一个共享变量,如果有多个线程并发的修改这个共享变量,最终得到的结果可能与我们想象的不太一样,这是由于JMM的机制导致的,而这和我们所说的volatile有什么关系的,那接下来我们就说说。结论:1:如果一个变量被volatile修饰,那么它在工作内存中修改的变量会立刻被刷新到主存中。而不是上面所说的不确定的时候2:如果读取一个被volatile修饰的变量,会把此线程工作内存中的此变量副本置为无效,它会从主内存中重新读取这个变量到自己的工作内存。上面这两点分别是volatile写内存语义和volatile内存语义。在JDK中,并发包中volatile把它的特点发挥到了极致,尤其通过框架AQS的state就是被volatile修饰的,在加上CAS构建出了无锁化的同步框架,在ConcurrentHashMap中也是因为有了volatile的作用加上CAS操作提高了很大的性能。上面3点只是简单的说明了volatile的作用,如果要详细介绍volatile,估计能够一本上百页的书了,在这里就不再详述了,如果想进一步了解volatile,请关注我的头条,我会有一个关于volatile的专题。

关键字volatile有什么含义

volatile是一个类型修饰符(type specifier),类似const一样,它是被设计用来修饰被不同线程访问和修改的变量。volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。

C语言中关键字volatile是什么意思

简单的理解就是这个变量可能会被外部函数改变,为了让这个改变能有效执行,不被编译器优化掉。举个例子吧,一个函数用了一个外部的变量,但这个变量在此函数中没有改变,只是引用,这时候编译器会去做优化,把它的值暂放在内部寄存器中,用的时候读取的是寄存器的值,而不是去访问它的地址取值,这样的话,当这个变量在外部发生了变化的时候,比如中断,或者另外的进程等等。但在这个函数里面就不能起作用,因为被优化后使用的是寄存器的值,还是原来的值,导致错误发生。这种情况下,就要加上这个定义,就不会被优化了。

java里面volatile是什么意思?

Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。x0dx0ax0dx0aJava语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。x0dx0ax0dx0a这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。x0dx0ax0dx0a而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。x0dx0ax0dx0a使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。x0dx0ax0dx0a由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。 x0dx0ax0dx0a就跟C中的一样 禁止编译器进行优化~~~~

C++中的volatile是什么意思?

  volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。  volatile的本意是“易变的”,不过翻译成“直接存取原始内存地址”更为合适。“易变”是因为外在因素引起的,象多线程,中断等,并不是因为用volatile修饰了的变量就是“易变”了,假如没有外因,即使用volatile定义,它也不会变化。
 1 2  下一页  尾页