barriers / 阅读 / 详情

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

2023-07-31 09:44:14
共1条回复
北有云溪

1、避免用通用寄存器对内存读写的优化。编译器常做的一种优化就是:把常用变量的频繁读写弄到通用寄存器中,最后不用的时候再存回内存中。但是如果某个内存地址中的值是由片外决定的(例如另一个线程或是另一个设备可能更改它),那就需要volatile关键字了。(感谢Kenny老师指正)

2、硬件寄存器可能被其他设备改变的情况。例如一个嵌入式板子上的某个寄存器直接与一个测试仪器连在一起,这样在这个寄存器的值随时可能被那个测试仪器更改。在这种情况下如果把该值设为volatile属性的,那么编译器就会每次都直接从内存中去取这个值的最新值,而不是自作聪明的把这个值保留在缓存中而导致读不到最新的那个被其他设备写入的新值。

3、同一个物理内存地址M有两个不同的内存地址的情况。例如两个程序同时对同一个物理地址进行读写,那么编译器就不能假设这个地址只会有一个程序访问而做缓存优化,所以程序员在这种情况下也需要把它定义为volatile的。

相关推荐

volatile关键字的作用

volatile在Java并发编程中常用于保持内存可见性和防止指令重排序。内存可见性(MemoryVisibility):所有线程都能看到共享内存的最新状态。防止指令重排:在基于偏序关系的Happens-Before内存模型中,指令重排技术大大提高了程序执行效率,但同时也引入了一些问题。volatile保持内存可见性的特殊规则:read、load、use动作必须连续出现;assign、store、write动作必须连续出现;每次读取前必须先从主内存刷新最新的值。注意事项每次写入后必须立即同步回主内存当中。也就是说,volatile关键字修饰的变量看到的随时是自己的最新值。在线程1中对变量v的最新修改,对线程2是可见的。volatile防止指令重排的策略:在每个volatile写操作的前面插入一个StoreStore屏障;在每个volatile写操作的后面插入一个StoreLoad屏障。在每个volatile读操作的后面插入一个LoadLoad屏障;在每个volatile读操作的后面插入一个LoadStore屏障。注意:只有在Happens-Before内存模型中才会出现这样的指令重排序问题。
2023-07-31 01:51:181

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

volatile是指易改变的。用他修饰的变量表明该变量是易发生改变的变量,每当优化器访问该变量时,都会重新读取该变量的值,而不是直接去找寄存器中找该变量的备份。例子: 1、并发的硬件寄存器,如状态寄存器。 2、中断服务器的子程序访问的非自动变量。 3、多线程中被多个任务共享的变量。
2023-07-31 01:51:311

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将停止循环。
2023-07-31 01:51:381

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

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

java里面volatile是什么意思?

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

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

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

关键字volatile有什么含义

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

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的专题。
2023-07-31 01:52:472

如何理解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的反义词。
2023-07-31 01:53:121

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

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

volatile类型变量有什么特点

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

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();
2023-07-31 01:53:401

关键字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线程进入死循环。
2023-07-31 01:53:481

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可以保证对特殊地址的稳定访问,不会出错。
2023-07-31 01:53:583

static 和 Volatile 的区别

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

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_;};
2023-07-31 01:54:241

static和volatile有哪些用途用途。

static是静态获取,volatile是从列表中获取
2023-07-31 01:54:332

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

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

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_;};
2023-07-31 01:54:501

哪些变量需要加volatile

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

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

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

C语言 中volatile关键字的用法

2023-07-31 01:55:304

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

不可以
2023-07-31 01:55:551

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

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

c语言什么时候用volatile

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

JAVA 里static 和volatile的区别

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

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

const 常量,运行时不可改变volatile 编译器不要优化(多用于寄存器)
2023-07-31 01:56:582

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

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

为什么 long 和double 加上volatile

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

extern volatile unsigned char idata 这算是什么定义?

extern volatile是用来进行线程间变量引用的定义。这个和const、static是平行的或者说同类的(功能不同)是一个类型修饰符unsigned char无符号字符变量idata 变量名。
2023-07-31 01:57:282

volatile关键字的作用是什么?

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

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; }}
2023-07-31 01:58:152

java里面volatile是什么意思?

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

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

C语言关键字volatile,表示不经过赋值,其值也可能被改变
2023-07-31 01:58:324

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将停止循环。
2023-07-31 01:58:422

关键字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线程进入死循环。
2023-07-31 01:58:491

java 里面volatile什么意思啊

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

volatile和lock的区别

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

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。
2023-07-31 01:59:141

关于c语言中的volatile限定符

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

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。
2023-07-31 01:59:451

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

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

关键字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可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
2023-07-31 02:00:011

JAVA 里static 和volatile的区别

static是静态的声明,volatile是重新配置
2023-07-31 02:00:082

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

http://zhidao.baidu.com/question/331268847.html
2023-07-31 02:00:183

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。
2023-07-31 02:00:251

Volatile修饰数组有意义吗

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

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_;};
2023-07-31 02:00:411

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

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

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

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