Java内存模型的历史变迁
转自:http://www.csdn.net/article/2015-05-20/2824722-Java
摘要:本文通过介绍Java的新/旧内存模型,来展示Java技术的历史变迁。
本文通过介绍Java的新/旧内存模型,来展示Java技术的历史变迁。
旧的Java内存模型
Java 使用的是共享内存的并发模型,在线程之间共享变量。Java语言定义了线程模型规范,通过内存模型控制线程与变量的交互,从而实现Java线程之间的通 信。在JDK5之前,Java一直使用的是旧内存模型。如图1所示。变量保存在由所有线程共享的主内存中,主内存中的变量称为mastingcopy。每 个线程都有一个工作内存,它保存变量的workingcopy。旧的内存模型定义了若干规则,通过这些规则来保证线程何时将主内存中的 mastingcopy传送到线程的工作内存中;以及线程何时将工作内存中的workingcopy传送回主内存。旧内存模型使用8个操作来定义线程可以 执行的动作。
- read(读)操作:主内存把mastingcopy传送到线程的工作内存,以供后面的load操作使用。
- load(装载)操作:线程将由read操作从主内存传送过来的值,放入工作内存中。
- use(使用)操作:线程将变量的workingcopy传送到线程执行引擎。
- assign(赋值)操作:线程将变量值从线程执行引擎传送到线程的工作内存中。
- store(存储)操作:线程将变量的workingcopy传送到主内存,供后面的write操作使用。
- write(写)操作:主内存将由store操作传送过来的值,放入主内存中。
- lock(锁定)操作:线程获得指定对象的锁。
- unlock(解锁)操作:线程释放指定对象的锁。
图1 Java旧内存模型
这里的关键是,由于read操作是由主内存执行,而对应的load是由线程执行,read操作和load操作之间是松散耦合的。也就是说,主内存和线程工作内存之间的变量传递是松散耦合的。同 样,由于store操作是由线程执行,而对应的write是由主内存执行,store操作和write操作之间是松散耦合的。也就是说,线程工作内存和主 内存之间的变量传递是松散耦合的。旧Java内存模型对Java实现如何执行变量的读/写,加锁/解锁,以及volatile变量的读/写,定义了非常严 格的规则。这些规则非常复杂,具体详情请参考《JVM规范》,这里就不赘述了。旧Java内存模型通过这些复杂的规则,来保证多线程程序的线程之间,可以可靠地传递共享变量,从而保证多线程程序的正确性。
新的Java内存模型
从JDK5开始,Java使用新的内存模型,新内存模型完全抛弃了旧内存模型的主内存和工作内存的概念,也抛弃了旧内存模型的8个内存操作。也就是说,新内存模型完全是重新设计的。
新内存模型引入了一个新的概念,叫happens-before。happens-before的概念最初由LeslieLamport在其一篇影响深远的论文(《Time,ClocksandtheOrderingofEventsinaDistributedSystem》)中提出。 LeslieLamport使用happens-before来定义分布式系统中,事件之间的一个偏序关系(partialordering)。 LeslieLamport在这篇论文中给出了一个分布式算法,该算法可以将该偏序关系扩展为某种全序关系。
JSR-133使用happens-before的概念来指定两个操作(这里的操作是指程序中对变量的读/写,对锁的加锁和解锁)之间的执行顺序。新内存模型定义了如下的happens-before规则:
- 程序顺序规则:一个线程中的每个操作,happensbefore于该线程中的任意后续操作。
- 监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的加锁。
- volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读。
- 传递性:如果A happens-before B,且B happens-before C,那么A happens-before C。
- start()规则:如果线程A执行操作ThreadB.start()(启动线程B),那么A线程的ThreadB.start()操作happens-before于线程B中的任意操作。
- join()规则:如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作happens-before于线程A从ThreadB.join()操作成功返回。
由于两个操作可以在一个线程之内,也可以是在不同线程之间。因此JMM可以通过happens-before关系向程序员提供跨线程的内存可见性保证(如果 A线程的写操作a与B线程的读操作b之间存在happens-before关系,尽管a操作和b操作在不同的线程中执行,但JMM
图2新内存模型的设计示意图
向程序员保证a操作将对b操作可见)。在新内存模型向程序员提供happens-before规则,程序员只需要与happens-before打交道即可,因此Java程序员的学习负担大大降低。 同时,新内存模型允许不会改变程序结果的重排序,这可以最大限度地放松对编译器和处理器的束缚,新内存模型的执行性能比旧内存模型要好。
作者简介:程晓明Java软件工程师,关注并发与NIO,《深入理解Java内存模型》的作者。现就职于南京富士通南大软件技术有限公司,从事富士通Interstage应用服务器的开发。
Java内存模型的历史变迁的更多相关文章
- java内存模型(转)
前提知识: Java内存模型(JMM)是一个概念模型,底层是计算机的寄存器.缓存内存.主内存和CPU等. 多处理器环境下,共享数据的交互硬件设备之间的关系: JMM: 从以上两张图中,谈一谈以下几个 ...
- 来,了解一下Java内存模型(JMM)
网上有很多关于Java内存模型的文章,在<深入理解Java虚拟机>和<Java并发编程的艺术>等书中也都有关于这个知识点的介绍.但是,很多人读完之后还是搞不清楚,甚至有的人说自 ...
- 再有人问你Java内存模型是什么,就把这篇文章发给他
前几天,发了一篇文章,介绍了一下JVM内存结构.Java内存模型以及Java对象模型之间的区别.有很多小伙伴反馈希望可以深入的讲解下每个知识点.Java内存模型,是这三个知识点当中最晦涩难懂的一个,而 ...
- JAVA内存模型及垃圾回收自我总结
本文为原创,根据<深入理解java虚拟机>和自己的一些理解进行整理,单纯和看其他人的博客感觉不如自己一点点的画和记录来的印象深刻. JAVA内存模型: 上图中:局部变量表所需的内存在编译期 ...
- 别再问什么是Java内存模型了,看这里!
网上有很多关于Java内存模型的文章,在<深入理解Java虚拟机>和<Java并发编程的艺术>等书中也都有关于这个知识点的介绍.但是,很多人读完之后还是搞不清楚,甚至有的人说自 ...
- Java 并发系列之三:java 内存模型(JMM)
1. 并发编程的挑战 2. 并发编程需要解决的两大问题 3. 线程通信机制 4. 内存模型 5. volatile 6. synchronized 7. CAS 8. 锁的内存语义 9. DCL 双重 ...
- java内存模型的实现
前几天,发了一篇文章,介绍了一下JVM内存结构.Java内存模型以及Java对象模型之间的区别.其中,Java内存模型,是这三个知识点当中最晦涩难懂的一个,而且涉及到很多背景知识和相关知识. 网上有很 ...
- 再问你Java内存模型的时候别再给我讲堆栈方法区
在介绍Java内存模型之前,先来看一下到底什么是计算机内存模型,然后再来看Java内存模型在计算机内存模型的基础上做了哪些事情.要说计算机的内存模型,就要说一下一段古老的历史,看一下为什么要有内存模型 ...
- JVM的艺术—JAVA内存模型
*喜欢文章,动动手指点个赞 * 引言 亲爱读者你们好,关于jvm篇章的连载,前面三章讲了类加载器,本篇文章将进入jvm领域的另一个知识点,java内存模型.彻底的了解java内存模型,是有必要的.只要 ...
随机推荐
- 叨叨PS那些活
临睡前记得今天技术小结没写...就起来叨叨些使用Photoshop做网站的活吧. 一般网站的建站流程和人员配置是: 1 美工,创建页面的psd图 2 前端工程师,根据psd图,切出html页面 3 后 ...
- MyBatis魔法堂:ResultMap详解
一.前言 MyBatis是基于“数据库结构不可控”的思想建立的,也就是我们希望数据库遵循第三范式或BCNF,但实际事与愿违,那么结果集映射就是MyBatis为我们提供这种理想与现实间转换的手段了, ...
- 由node-webkit想到
本人做为.NET的死忠也有些许年头.微软这几年被谷歌苹果之流打的有点招架不住..NET的前景也难免堪忧.虽然我认为就强类型语言方面,C#绝对是最强者.但是新技术的发展确实是可怕的,看看苹果几年就把no ...
- WCF开发框架之插件化应用模式升级
自从在<Winform开发框架之插件化应用框架实现>一文中,介绍并总结了Winform开发框架插件化应用框架的实现后,赢得了很多同行和客户的支持,于是把我的WCF开发框架.混合式开发框架都 ...
- Ext.GridPanel 用法总结(一)—— Grid基本用法
Ext.GridPanel 用法总结(一)—— Grid基本用法 摘自:http://www.cnblogs.com/luluping/archive/2009/08/01/1536645.html ...
- MarkDown学习记录
一.基本语法 1.标题 建议在#后面加一个空格 2.列表 注意:符号和文字之间加上一个字符的空格 3.引用 4.链接 5.图片 6.粗体与斜体 7.代码框 8.分隔符 二.参考文章 http://ww ...
- 重新想象 Windows 8.1 Store Apps (74) - 新增控件: Flyout, MenuFlyout, SettingsFlyout
[源码下载] 重新想象 Windows 8.1 Store Apps (74) - 新增控件: Flyout, MenuFlyout, SettingsFlyout 作者:webabcd 介绍重新想象 ...
- 晒自己做的一个管理系统(清新风格)EasyUI
最近项目结束了,现在也要自己总结一下自己的成果了,总结会加深自己对项目的印象的.这里我就先晒一些作品图片了,希望大家看了会赞美一个! 项目虽然结束了,但是接下来的这个项目可就不是我一个人可以搞定的了, ...
- tomcat filewatchdog but has failed to stop it原因以及解决方法
停止tomcat,有些时候会报The web application [/XXX] appears to have started a thread named [FileWatchdog] but ...
- mybatis/callablestatement调用存储过程mysql connector产生不必要的元数据查询
INFO | jvm 1 | 2016/08/25 15:17:01 | 16-08-25 15:17:01 DEBUG pool-1-thread-371dao.ITaskDao.callProce ...