- 浏览: 124352 次
- 性别:
- 来自: 上海
文章分类
最新评论
源地址: http://blog.csdn.net/maritimesun/article/details/7838838
volatile关键字在我们接触较多的几种语言C/C++/Java中均存在,在并发编程方面也会用到,因此还是有必要了解。
1 volatile关键字在java并发编程下的应用
Java中设置变量值的操作,除了long和double类型的变量外都是原子操作,关于long和double类型变量的非原子性问题,可参考《long和double类型变量的非原子性》一文。也就是说,对于变量值的简单读写操作没有必要进行同步。在JVM 1.2之前,Java的内存模型实现总是从主存读取变量,是不需要进行特别处理的。而随着JVM的成熟和优化,在当前的Java内存模型下,线程可以把变量保存在本地内存(比如寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,会造成数据的不一致。要解决这个问题,只需要在程序中把该变量声明为volatile(不稳定的)即可,这就指示JVM这个变量是不稳定的,每次使用它都到主存中进行读取。一般说来,多任务环境下各任务间共享的标志都应该加volatile修饰。
volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。 说白了,其实就是volatile关键字的变化可见的功能,当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。 那么,大家也注意到了,使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低。
使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。
为使大家更容易理解,结合C++下的例子,给大家做个演示。
2 C++下volatile关键字的使用案例
用volatile关键字声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到volatile关键字声明的变量,编译器对访问该变量的代码不再进行优化,从而可以提供对特殊地址的稳定访问。
使用该关键字的例子如下:
int volatile nVint;
当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。(这其实就是在第一部分中提到的每次使用都到主存中进行读取)。
例如:
volatile int i=10; int a = i; ... //其他代码,并未明确告诉编译器,对i进行过操作 int b = i;
volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问。
注意,在vc6中,一般调试模式没有进行代码优化,所以这个关键字的作用看不出来。下面通过插入汇编代码,测试有无volatile关键字,对程序最终代码的影响:
首先,用classwizard建一个win32 console工程,插入一个voltest.cpp文件,输入下面的代码:
#include <stdio.h> void main() { int i=10; int a = i; printf("i= %d\n",a); //下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道 __asm { mov dword ptr [ebp-4], 20h } int b = i; printf("i= %d\n",b); }
然后,在调试版本模式运行程序,输出结果如下:
i = 10 i = 32
然后,在release版本模式运行程序,输出结果如下:
i = 10 i = 10
输出的结果明显表明,release模式下,编译器对代码进行了优化,第二次没有输出正确的i值。下面,我们把 i的声明加上volatile关键字,看看有什么变化:
#include <stdio.h> void main() { volatile int i=10; int a = i; printf("i= %d\n",a); __asm { mov dword ptr [ebp-4], 20h } int b = i; printf("i= %d\n",b); }
分别在调试版本和release版本运行程序,输出都是:
i = 10 i = 32
这说明这个关键字发挥了它的作用!
发表评论
-
(转)JDK工具(查看JVM参数、内存使用情况及分析等)
2018-12-25 15:50 345https://www.cnblogs.com/z ... -
[转]jstat查看jvm的GC情况
2018-12-25 15:38 553jstat 1. jstat -gc pid ... -
转一个 jmap 的基本使用方法
2017-04-05 11:52 535原文:http://hbluojiahui.bl ... -
(转)JVM内存堆布局图解分析
2017-04-05 11:56 403转载原文出处:http://www.codeceo.com/ ... -
(转)系统吞吐量(TPS)、用户并发量、性能测试概念和公式
2017-03-27 11:19 452PS:下面是性能测试的主要概念和计算公式,记录下: 一.系 ... -
(转)深入理解Major GC, Full GC, CMS
2016-11-02 11:27 499原文:http://blog.csdn.net/iter_ ... -
(转)OpenSSL 1.0.0生成p12、jks、crt等格式证书的命令个过程
2016-07-26 18:51 664OpenSSL 1.0.0生成p12、jks、crt等格式 ... -
(转)Java 内存区域和GC机制
2016-07-26 14:09 368录 Java垃圾回收概况 Java内存区域 Java ... -
Understanding CMS GC Logs
2016-07-26 11:06 532Understanding CMS GC Logs By ... -
(转)Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
2016-07-08 17:56 600源地址:http://blog.csdn.net/lu ... -
linux下查看最占性能的JAVA进程
2016-03-08 11:58 634记录一下自己常用的linux系统命令,方便以后查阅,发觉记忆 ... -
(转,精)Java 多线程 并发编程
2015-10-10 19:50 800源地址:http://blog.csdn.n ... -
java虚拟机内存监控工具jps,jinfo,Jstack,jstat,jmap,jhat使用
2015-09-21 13:14 1202源地址:http://my.oschina. ... -
(转)JMM模型
2014-11-11 16:53 488源地址:http://blog.csdn.net/gt ... -
(转)《深入浅出 Java Concurrency》目录
2014-11-10 15:55 402原文地址:http://www.blogjava.net/x ... -
(转)TCP/IP、Http、Socket的区别
2014-08-21 10:32 813源地址: http://jingyan.baidu.com/ ... -
(转)Swift里的CAP理论和NWR策略应用
2014-08-12 17:25 612源地址:http://blog.sina.com.cn/s/ ... -
(转)Java多线程编程的常见陷阱
2014-06-25 13:14 498源地址:http://developer.51cto.com ... -
(转)Java 正确的做字符串编码转换
2014-03-11 21:52 657原文:http://hi.baidu.com/sodarf ... -
深入理解java内存模型系列文章
2013-12-30 10:57 438深入理解java内存模型系列文章 源地址: htt ...
相关推荐
深入理解volatile关键字 volatile关键字是Java语言的高级特性,它可以保证可见性和禁止指令重排序,但是要弄清楚其工作原理,需要先弄懂Java内存模型。 保证可见性 volatile关键字可以保证可见性,即当一个线程...
### AVR-GCC 中如何使用 `volatile` 关键字 #### 1. `volatile` 关键字的基本概念 在编程语言中,尤其是C/C++中,`volatile` 是一个类型限定符,用来修饰变量,告知编译器该变量的值可能会在编译器未监控的情况下...
Java并发编程中,volatile关键字扮演着重要的角色,它是一种轻量级的同步机制,与synchronized相比,volatile在性能上更优,因为它不会导致线程阻塞。在深入理解volatile的关键特性之前,我们需要先了解Java内存模型...
java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java ...
《面试官最爱的volatile关键字详解》 在Java编程中,volatile关键字是一个至关重要的概念,尤其在多线程环境下,理解并正确使用volatile是面试时必不可少的知识点。volatile被视为synchronized的一种轻量级实现,但...
`volatile`关键字在C语言中是一个非常重要的概念,主要用于指示编译器某个变量的值可能会在编译器无法预测的情况下发生变化,例如由硬件中断、并发操作或其他非程序控制的手段改变。这使得编译器在处理`volatile`...
在Java编程语言中,`volatile`关键字是一个非常关键的同步原语,用于处理并发编程中的可见性和有序性问题。这个关键字对于理解Java内存模型(JMM)以及如何编写线程安全的代码至关重要。下面我们将从多个角度深入...
java里的volatile关键字详解.pdf
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
### Java并发编程:volatile关键字解析 #### 一、内存模型的相关概念 在深入了解`volatile`关键字之前,我们首先需要理解计算机内存模型的一些基本概念。在现代计算机系统中,CPU为了提高执行效率,会将频繁访问的...
volatile
详解C中volatile关键字 volatile关键字是C语言中一个重要的关键字,它对变量的声明在不同编译环境下可能造成不同的结果。volatile关键字的作用是提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序...
### Java关键字详解 #### 概述 Java是一种广泛使用的面向对象编程语言,它以其平台无关性、健壮性和安全性而闻名。Java中的关键字是预定义的保留字,具有特殊的意义和用途,不能用作标识符(如变量名、类名等)。在...
在Java并发编程中,volatile关键字是一种轻量级的同步机制,它用于确保变量的可见性和有序性。本文将详细探讨volatile关键字的工作原理、使用场景以及如何在实际开发中正确使用volatile。 volatile关键字是Java并发...
在C++编程语言中,`const`、`volatile`和`mutable`是三个非常重要的关键字,它们用于控制变量、指针和引用的行为。本文将详细阐述这三个关键字的用途和应用场景。 首先,`const`关键字主要用于声明常量或者使得变量...
《Keil C51基本关键字详解》 Keil C51是专为8051微控制器设计的一种高级编程语言,它提供了丰富...通过深入学习《Keil C51基本关键字.pdf》这份资料,你将能够掌握C51编程的关键,进一步提升你的嵌入式系统开发能力。
"Java中的Volatile关键字详解" Java中的Volatile关键字详解是Java中的一种关键字,用于保证线程之间的可见性、原子性和有序性。下面是对Java中的Volatile关键字详解的知识点总结: 一、基本概念 1. 可见性:可见...
在IT行业中,volatile关键字在编程,尤其是嵌入式系统和多线程编程中扮演着重要的角色。本篇文章将深入探讨volatile关键字的作用,并结合GD32F303单片机的使用场景,来阐述它在实际开发中的应用。 首先,volatile...
C 语言关键字解读 C 语言关键字是 C 语言的基本组成部分,它们是构成 C 语言程序的基础单元。在 C 语言中,关键字是预定义的符号,具有特殊的含义和用途。今天,我们将对 C 语言关键字进行深入解读,了解它们的分类...
与const相对的是volatile关键字,它用于声明易变的数据,表明数据的值可能在程序的控制之外被改变,因此每次使用该数据时都需要从内存中重新读取。return关键字用于从函数中返回一个值,而continue关键字用于结束...