从单例模式挖到内存模型(三)----volatile关键字
来源:互联网 发布:下载九块九淘宝官网址 编辑:程序博客网 时间:2024/06/10 21:28
volatile这个单词在英文中的意思是:易变的,不稳定的。这个关键字在java中就是表示某个变量是不稳定的,java会有自己的方式去处理这种变量。
java对volatile的定义:
java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致的更新,线程应该确保通过排它锁单独获得这个变量。
当一个变量定义为 volatile 之后,将具备两种特性:
1,保证此变量对所有的线程的可见性。当一个线程修改了这个变量的值,volatile保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新。但普通变量做不到这点,当对非 volatile 变量进行读写的时候,每个线程先从主内存拷贝变量工作内存中,变量在工作内存中被修改后,不会立即同步到主内存。
2,禁止指令重排序优化。有volatile修饰的变量,赋值后多执行了一个“load addl $0x0, (%esp)”操作,这个操作相当于一个内存屏障(指令重排序时不能把后面的指令重排序到内存屏障之前的位置),只有一个CPU访问内存时,并不需要内存屏障。
volatile 性能:
volatile 的读性能消耗与普通变量几乎相同,但是写操作稍慢,因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。
volatile不保证操作的原子性
volatile不保证操作的原子性,验证的例子很简单,开100个线程给一个数字做i++的操作,数字增加的结果和操作次数并不一致。
volatile不保证操作的原子性的原因:volatile只保证从主内存复制到工作内存的变量是最新的(因为变量改变后立刻从工作内存刷新到主内存),但已经读到工作内存的变量不会因为别的线程刷新了主内存而发生改变。
举例:线程A和线程B都修改变量x=10,x是用volatile修饰的。
结果正确的情况:
1,线程A从主内存中读取变量x,复制到A的工作内存(x=10)。
2,线程A操作x++,并立刻刷新到主内存(主内存x=11)。
3,线程B从主内存读取变量x,复制到B的工作内存(x=11)。
如果x没有volatile修饰,这个时候线程A可能还没有把x=11刷新到主内存,这个时候线程B得到的x就可能是10。
4,线程B操作x++,并立刻刷新到主内存(主内存x=12)。
结果错误的情况:
1,线程A从主内存中读取变量x,复制到A的工作内存(x=10)。
2,线程B从主内存读取变量x,复制到B的工作内存(x=10)。volatile并不阻塞线程,所以多线程情况下有可能两个线程都从主线程读取了同一个变量。
3,线程A操作x++,并立刻刷新到主内存(主内存x=11)。
4,线程B操作x++,并立刻刷新到主内存(主内存x=11),这个结果并不正确。
不能把volatile当成synchronize这样的锁来用,如果要用他来满足线程安全需要符合以下条件:
1,对变量的写操作不依赖于当前值。
2,该变量没有包含在具有其他变量的不变式中。
最后,很多高手建议:尽量别用volatile这个关键字,很容易就用错了。
- 从单例模式挖到内存模型(三)----volatile关键字
- 从单例模式挖到内存模型(四)----java内存模型
- 从单例模式挖到内存模型(一)----单例模式和双检锁
- 从单例模式挖到内存模型(二)----指令重排序
- 从Java内存模型理解synchronized、volatile和final关键字
- volatile关键字解析&内存模型&并发编程中三概念
- volatile关键字解析&内存模型&并发编程中三概念
- Java内存模型&volatile关键字
- Java并发编程:volatile关键字解析(三.Java内存模型)
- Java内存模型(三)-Volatile
- java volatile关键字 使用说明以及JMM(java 内存模型)
- java基础知识(五)java内存模型和volatile关键字
- Java多线程-带你认识Java内存模型,内存分区,从原理剖析Volatile关键字
- Java内存模型与volatile关键字
- Java内存模型与volatile关键字
- Java内存模型与volatile关键字
- 由volatile关键字谈Java内存模型
- 由volatile关键字谈Java内存模型
- Sublime Text 3如何快速生成HTML5的头部信息和常用的快捷键
- 【转】优秀程序员不得不知道的20个位运算技巧
- 基于ARM9处理器的工作模式&工作状态&寄存器&异常类型总结笔记
- 自动化测试中java多线程的使用实例
- qmake 如何配置生成的object不在同一目录下
- 从单例模式挖到内存模型(三)----volatile关键字
- raspberri pi 3 + v2 camera 树莓派摄像头 发布到ros 节点上 远程电脑查看视频
- javascript中cookie使用--登录记住密码
- Windows-Perl-JSON
- git教程
- bootstrap-table 初始化数据及使用问题
- 判断身份证手机号码正则表达式
- 动态分段(线性参考)在SuperMap中的使用
- 基于vue前端框架/scrapy爬虫框架/结巴分词实现的小型搜索引擎