对于volatile的理解
哎.要学的东西太多,时间太少.一周的工作下来要总结的东西太多,还处理不完,越积越多.大周末的好想出去玩啊.... 得嘞,废话止于此.
无聊时候乱看网页发现了volatile的一篇文章,以前曾经对volatile困惑过..所以在学习一遍http://blog.sina.com.cn/s/blog_559f6ffc01000aip.html
volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
例如:
>>>>当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。也不会从寄存器重新读取而是从内存中重新读取
例如:
volatile int i=10;
int a = i; ----->//从内存中读取
...//其他代码,并未明确告诉编译器,对i进行过操作
...//其他代码,并未明确告诉编译器,对i进行过操作
int b = i;------->并不会从寄存器中读取i的值而是又一次从内存中读取i的值
>>>>volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问。
volatile对应的变量可能在你的程序本身不知道的情况下发生改变
比如多线程的程序,共同访问的内存当中,多个程序都可以操纵这个变量
你自己的程序,是无法判定何时这个变量会发生变化
还比如,他和一个外部设备的某个状态对应,当外部设备发生操作的时候,通过驱动程序和中断事件,系统改变了这个变量的数值,而你的程序并不知道。
对于volatile类型的变量,系统每次用到他的时候都是直接从对应的内存当中提取,而不会利用cache当中的原有数值,以适应它的未知何时会发生的变化。
典型的例子
for ( int i=0; i<100000; i++);
这个语句用来测试空循环的速度的
但是编译器肯定要把它优化掉,根本就不执行
如果你写成
for ( volatile int i=0; i<100000; i++);
它就会执行了
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1). 并行设备的硬件寄存器(如:状态寄存器)
2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3). 多线程应用中被几个任务共享的变量
假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。
1). 一个参数既可以是const还可以是volatile吗?解释为什么。
2). 一个指针可以是volatile 吗?解释为什么。
3). 下面的函数有什么错误:
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;
}
总结就是,对于共享变量而言,这个变量有可能改变了,但这种改变并不是你所关注的程序(代码)造成的.这种情况下编译器可能会认为这个共享变量没有改变而直接使用改变前的值.而我们加上vialoate后就是在告诉编译器,不要直接用上次的值,给我从内存里面重新读取!!
对于volatile的理解的更多相关文章
- Java线程工作内存与主内存变量交换过程及volatile关键字理解
Java线程工作内存与主内存变量交换过程及volatile关键字理解 1. Java内存模型规定在多线程情况下,线程操作主内存变量,需要通过线程独有的工作内存拷贝主内存变量副本来进行.此处的所谓内存模 ...
- volatile变量理解 via《Java并发编程实战》
第3章:对象的共享 volatile关键字的理解 volatile变量,用来确保将变量的更行操作通知到其他线程.当变量申明为volatile类型后,编译器与运行时都会注意带这个变量时共享的,因此不会将 ...
- 对volatile的理解--从JMM以及单例模式剖析
请谈谈你对volatile的理解 1.volitale是Java虚拟机提供的一种轻量级的同步机制 三大特性1.1保证可见性 1.2不保证原子性 1.3禁止指令重排 首先保证可见性 1.1 可见性 概念 ...
- volatile的理解
用法解释 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其 ...
- volatile的理解和使用
package thread; /** * Created by Administrator on 2017/1/15. */ public class Counter { public volati ...
- 关于java多线程关键字volatile的理解
volatile关键字的作用是强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中取得变量的值. 使用volition关键字增加了实例变量在多个线程间的可见性.但volition有个致命的缺点就是不 ...
- (转)volatile 的理解
对于(volatile unsigned char *)0x20我们再分析一下,它是由两部分组成: 1) (unsigned char *)0x20,0x20只是个值,前面加(unsigned cha ...
- Volatile关键字理解
Volatile定义 为了确保共享变量能被准确和一致的更新,线程应该确保通过排他锁单独获得这个变量.Java语言提供了volatile,在某些情况下比锁更加方便.如果一个字段被声明成volatile, ...
- java中关于volatile的理解疑问?
作者:xyzZ链接:https://www.zhihu.com/question/49656589/answer/117826278来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
随机推荐
- myEclipse和eclipse修改或复制项目名称后-更新部署名称
一.myEclipse 复制后修改名称,访问不到项目 这是因为,你只是改了项目的名称,而没有改 下面是解决方法: 方法 1.右击你的项目,选择“properties”,在“type filter te ...
- CSS Sprites的详细使用步骤
一.把小图放在一张大图中,先排版好.上几张图看看,就比如这个: 谷歌: 淘宝: 土豆右下角悬浮框: 1.把用到的小图都放到了一张大图里,其中的小图之间的排版是有点规律的,比如说淘宝那张,类似的小图放置 ...
- CSS3之设计动态立体盒子
CSS3设计3D效果图 使用到CSS3中的变形.缩放.倾斜. 只写了兼容Gecto的.发张图片鼓励自己 <!DOCTYPE html> <html> <head> ...
- easyui常用控件样式收藏
CSS类定义: div easyui-window window窗口样式 属性如下: 1) modal:是否生成模态窗口.tru ...
- innodb_space工具解析 MYSQL 页图解
- Chapter 6 - How to Play Music and Sound Effect
In this chapter, we would add background music to the game and play sound effect when the hero fires ...
- AFNetWorking源码详解(二)
来源:Yuzeyang 链接:http://zeeyang.com/2016/03/15/AFNetWorking-two/ AFHTTPSessionManager继承于AFURLSessionMa ...
- codeforces 505C Mr. Kitayuta, the Treasure Hunter(dp)
题意:有30001个岛,在一条线上,从左到右编号一次为0到30000.某些岛屿上有些宝石.初始的时候有个人在岛屿0,他将跳到岛屿d,他跳跃的距离为d.如果当前他跳跃的距离为L,他下一次跳跃的距离只能为 ...
- like的性能问题
使用like'%匹配的文字%',无法优化,因为索引起不到作用. 不过like'匹配的文字%',索引起作用.
- svn项目冲突时显示无法加载项目的解决方法
1.无法加载的项目会显示成灰色.这是右键点击编辑 打开后去掉乱字符. 2.完成后会有红色的叹号 这是右键 找到解决冲突即可 然后提交