对java 内存可见性的理解
来源:互联网 发布:周立功单片机官网 编辑:程序博客网 时间:2024/04/28 01:46
同步包括两方面的含义: 独占性和可见性。
很多人仅仅理解了独占性,而忽略了可见性。
根据Java Language Specification中的说明, jvm系统中存在一个主内存(Main Memory或Java Heap Memory),Java中所有变量都储存在主存中,对于所有线程都是共享的。
每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。
一种常见的错误是,只有在写入共享变量时才需要同步,而读取的时候并不需要同步。
publicclass GetAndSet { privateint i; publicint getI() { returni; } publicsynchronized void setI(int i) { this.i = i; }}
在多线程环境中,仅从独占性上分析,上述程序根本不存在任何问题。
问题出在了可见性上,
即,如果调用
在线程A中:setI(10);
然后在线程B中:getI();
得到的很可能并非10,这个我们想要的答案。
这是因为并没有什么保证,在线程A设置的I,在线程B中可以立马看到当前值。
Java内存模型就是为了解决可见性的问题。
JMM规定了JVM必须遵循的一组最小保证,这组保证规定了对变量的写入操作在何时将对于其他线程是可见的。
这组保证就是Happen-Before 规则。
happen before规则: Each action in a thread happens before everyaction in that thread that comes later in the program's order. An unlock on a monitor happens before everysubsequent lock on that same monitor. A write to a volatile field happens before everysubsequent read of that same volatile. A call to start() on a thread happens before anyactions in the started thread. All actions in a thread happen before any otherthread successfully returns from a join() on that thread.
happen before翻译过来就是:
程序顺序规则:一个线程中的每个操作,happens- before 于该线程中的任意后续操作。
监视器锁规则:对一个监视器锁的解锁,happens- before 于随后对这个监视器锁的加锁。
volatile变量规则:对一个volatile域的写,happens- before 于任意后续对这个volatile域的读。
传递性:如果Ahappens- before B,且B happens- before C,那么A happens- before C。
Thread.start()的调用会happens-before于启动线程里面的动作。
Thread中的所有动作都happens-before于其他线程从Thread.join中成功返回。
Happen-Before 规则是由JVM提供的,因此无论有没有“同步协助(synchronized,lock ,volatile,final)”,程序执行时都必须遵守这些规则, 只不过这些规则中的大部分和同步协助有关系。
注意:第一条程序顺序规则,按字面意思的话,在同一个线程中所有语句的执行过程,必须按照程序流的先后去执行。不可能有任何重排序的可能。
实际情况并非如此,在同一个线程中,只有有数据相关的操作才不会被重排序,而没有任何关系的操作是可以被编译器发现,并进行适当重排的。
如:inti =10; ————–a
intj =1;———————-b
i =i+1;———————-c
虽然 a hanppen before b, 可在真实执行的时候,b有可能会在a前执行。因为该线程根本无法感知这种顺序的变化。
可是,a 不可能在c前面执行,因为这个线程本身可以感知这个顺序的变化。
转自:http://blog.csdn.net/bingjing12345/article/details/20474015
- 对java 内存可见性的理解
- 对java 内存可见性的理解
- 对java 内存可见性的理解
- java的内存可见性
- 对 原子性,可见性的理解
- java内存可见性
- java内存可见性
- java 内存可见性
- JAVA 内存可见性
- JAVA多线程的内存可见性
- Java多线程中内存的可见性
- 对java内存的理解
- Java并发 可见性 理解
- Java多线程内存可见性
- Java多线程:内存可见性
- JAVA多线程内存可见性
- 【Java并发】内存可见性
- JAVA内存的可见性和指令的reorde
- win7 64位安装wamp缺失vcruntime140.dll和api-ms-win-crt-runtime-l1-1-0.dll 等
- HDU 4886 TIANKENG’s restaurant(Ⅱ) (哈希)
- Mybatis的数据库字段类型JDBCType和java基本数据类型转换说明
- Docker命令介绍及实战
- 关于cocos2d中物理引擎碰撞掩码的设置
- 对java 内存可见性的理解
- 深入分析java web技术内幕----读书笔记(六)
- 胆囊炎患者日常饮食应该注意什么
- RecyclerView、ListView实现单选列表
- Windows 句柄泄露学习总结
- 【知识库】为什么把占空间的字段单独存一张表--mysql表设计(146)
- 【Lua知识整理】——Lua栈
- Centos安装Wordpress权限问题
- es5--js实现对象注册