浅谈volatile与automicInteger
在并发环境中有三个因素需要慎重考量,原子性、可见性、有序性。
voatile 保证了有序性(防止指令冲排序)和变量的内存可见性(每次都强制取主存数据),每次取到volatile变量一定是最新的
volatile主要用于解决可见性,它修饰变量,相当于对当前语句前后加上了“内存栅栏”。使当前代码之前的代码不会被重排到当前代码之后,当 前代码之后的指令不会被重排到当前代码之前,一定程度保证了有序性。而volatile最主要的作用是使修改volatile修饰的变量值时会使所有线程中的缓存失效,并强制写入公共主存,保证了各个线程的一致。可以看做是轻量级的Synchronized。详情可参看:
automicXXX主要用于解决原子性,有一个很经典的问题:i++是原子性的操作码?答案是不是,它其实是两步操作,一步是取i的值,一步是++。在取值之后如果有另外的线程去修改这个值,那么当前线程的i值就是旧数据,会影响最后的运算结果。使用automicXXX就可以非阻塞、保证原子性的对数据进行增减操作。详情可参看:http://ifeve.com/java-atomic/
volatile原理:
1.volatile可以保证线程可见性,且提供了一定的有序性,但无法保证原子性。
1.保证可见性,不保证原子性
2.禁止指令重排序
2.JVM底层,volatile采用 "内存屏障" 来实现
可见性实现:
可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值
synchronize和锁都可以保证可见性。
线程本身并不直接与主存进行数据交换,而是通过线程的工作内存来完成相应的操作 --- 线程间数据不可见的根本原因!!!
volatile实现可见性,直接从这方面入手,
1.修改volatile变量时,会强制将修改后的值刷新到主内存中
2.修改volatile变量后,会导致其他线程工作内存中对应的变量值失效,再读取该变量值时,要重新从主内存中读取
有序性实现:
关于重排序:
编译器重排序:不改变单线程语义的前提下,可以重新安排语句的执行顺序
处理器重排序:不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序
指令重排序对单线程无影响,但会影响多线程的正确性,
JVM如何禁止重排序?
happens-before 原则:保证程序的有序性
---------------------
作者:拉萨之虎2012
来源:CSDN
原文:https://blog.csdn.net/dan1289095756/article/details/80803977
版权声明:本文为博主原创文章,转载请附上博文链接!
最新文章
- hadoop 2.7.3本地环境运行官方wordcount
- WPF多源绑定
- [.net 面向对象程序设计进阶] (13) 序列化(Serialization)(五) Json 序列化利器 Newtonsoft.Json 及 通用Json类
- 关于history的Linux命令行
- oracle表分区详解(按天、按月、按年等)
- bbs树形打印(一)
- C语言位取反问题
- oracle sql语言模糊查询--通配符like的使用教程
- 多路径(multi-path)安装测试实例
- C#高级
- 无法升级数据库....因为此版本的 SQL Server 不支持该数据库的非发布版本(539) 解决方案
- (摘录)SQL Server 存储过程
- C# List 扩展排序
- 浅谈面试中的OOD面向对象设计问题
- 说说我心中的Linux系统
- javaWeb使用百度编辑器上传图片的问题
- 【codeforces 983E】NN country
- java DTO对象与PO对象的相互转换
- vector创建二位数组
- 【Diary】期中考+春游记
热门文章
- React 与 Redux 在生产环境中的实践总结
- MIT-6.824 Lab 3: Fault-tolerant Key/Value Service
- 使用Django简单编写一个XSS平台
- Codeforces Round 542 (Div. 2)
- Eclipse中从svn中检出maven项目
- Web大前端面试题-Day2
- 关于js操作符需要注意的地方
- Ⅳ.Catalan数
- Vmaware复制后的虚拟机不能上网问题解决
- Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) E. Tree Folding 拓扑排序