Java内存模型系列简介
来源:互联网 发布:威客网络兼职可靠吗 编辑:程序博客网 时间:2024/06/11 03:50
JMM
Java内存模型的抽象示意图:
Java线程间消息通信:
线程A将x=1传递给线程B,经历过程如下:
- 首先,线程A把本地内存A中更新过的共享变量刷新到主内存中去。
- 然后,线程B到主内存中去读取线程A之前已更新过的共享变量。
至于如何保证线程间数据的准确性,则需要利用同步锁来配合。
重排序
从java源代码到最终实际执行的指令序列,会分别经历下面三种重排序:
重排序重点理解以下原则:
- 数据依赖性原则
- as-if-serial语义
- happens-before
- 控制依赖关系
- 顺序一致性
重排序带来的问题就是程序执行结果会被改变。因此需要各种约定、规范来限制部分编译器、处理器重排序。
数据依赖性原则:对于两个操作A、B存在依赖关系的,编译器、处理器不会改变其执行顺序。
as-if-serial语义:对于单线程程序,无论怎么重排序,程序结果不能改变。
happens-before:前一操作结果对后一操作可见;前一操作按顺序排在后一操作前。
控制依赖关系:if、while等控制依赖,多线程中依旧会重排序。
顺序一致性:理想的内存模型,线程内操作必须有序。
锁
锁是java并发编程中最重要的同步机制。锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息。下面是锁释放-获取的示例代码:
class MonitorExample { int a = 0; public synchronized void writer() { //1 a++; //2 } //3 public synchronized void reader() { //4 int i = a; //5 …… } //6}
下面对锁释放和锁获取的内存语义做个总结:
- 线程A释放一个锁,实质上是线程A向接下来将要获取这个锁的某个线程发出了(线程A对共享变量所做修改的)消息。
- 线程B获取一个锁,实质上是线程B接收了之前某个线程发出的(在释放这个锁之前对共享变量所做修改的)消息。
- 线程A释放锁,随后线程B获取这个锁,这个过程实质上是线程A通过主内存向线程B发送消息。
final域
写final域的重排序规则
写final域的重排序规则可以确保:在对象引用为任意线程可见之前,对象的final域已经被正确初始化过了。
读final域的重排序规则
读final域的重排序规则可以确保:在读一个对象的final域之前,一定会先读包含这个final域的对象的引用。
参考
Java内存模型系列资料http://ifeve.com/java-memory-model-0/
阅读全文
1 0
- Java内存模型系列简介
- java内存模型简介
- Java 内存模型简介
- Java并发系列-9、Java内存模型
- Java内存模型中的三个代简介
- java 内存模型(JMM)简介
- 深入理解java内存模型系列文章
- 深入理解Java内存模型系列篇
- java学习系列4(内存模型)
- JVM内存模型简介
- java 深入理解Java内存模型之系列篇
- Java并发编程系列(一):Java并发内存模型
- 【java多线程系列】java内存模型与指令重排序
- 内存研究系列 - 内存模型
- 深入理解Java内存模型之系列篇
- 深入理解Java内存模型之系列篇
- 深入理解Java内存模型之系列篇
- 深入理解Java内存模型之系列篇
- DDL、DML、DQL、DCL之间的区别
- javascript输入某年月某日,判断是这一年的多少天
- Hadoop2.7.3在CentOS 6.5中的集群搭建
- 爬虫之旅(一)
- 素数环
- Java内存模型系列简介
- 51Nod-1781-Pinball
- Oracle 11gR2 RAC 常用维护操作 说明
- mysql数据库管理系统
- K
- TCP/IP 详解卷一学习笔记(二):网络层 IP
- shell基本语法及实现彩色进度条
- class object trait 区别
- 微信小程序之多行文本省略号