转自: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内存模型的历史变迁相关推荐

  1. Java内存模型深度剖析

    作者:Hollis,阿里资深攻城狮 来自:Hollis 为什么要有内存模型 在介绍Java内存模型之前,先来看一下到底什么是计算机内存模型,然后再来看Java内存模型在计算机内存模型的基础上做了哪些事 ...

  2. 再有人问你Java内存模型是什么,就把这篇文章发给他

    前几天,发了一篇文章,介绍了一下JVM内存结构.Java内存模型以及Java对象模型之间的区别.有很多小伙伴反馈希望可以深入的讲解下每个知识点.Java内存模型,是这三个知识点当中最晦涩难懂的一个,而 ...

  3. JAVA内存模型及垃圾回收自我总结

    本文为原创,根据<深入理解java虚拟机>和自己的一些理解进行整理,单纯和看其他人的博客感觉不如自己一点点的画和记录来的印象深刻. JAVA内存模型: 上图中:局部变量表所需的内存在编译期 ...

  4. 再有人问你Java内存模型是什么,就把这篇文章发给他。

    前几天,发了一篇文章,介绍了一下JVM内存结构.Java内存模型以及Java对象模型之间的区别.有很多小伙伴反馈希望可以深入的讲解下每个知识点.Java内存模型,是这三个知识点当中最晦涩难懂的一个,而 ...

  5. Java内存模型分析

    Java内存模型深入分析 0x01 内存模型产生的历史背景 曾经,计算机的世界远没有现在复杂,那时候的cpu只有单核,我们写的程序也只会在单核上按代码顺序依次执行,根本不用考虑太多. 后来,随着技术的 ...

  6. 史上最清晰的Java内存模型介绍

    这篇文章的标题看起来很霸气,于是我毫不犹豫转了~并且同样起了个霸气侧漏的标题! 本文转载自:再有人问你Java内存模型是什么,就把这篇文章发给他. 网上有很多关于Java内存模型的文章,在<深入 ...

  7. 一文深度分析Java内存模型

    0x01 内存模型产生的历史背景 曾经,计算机的世界远没有现在复杂,那时候的cpu只有单核,我们写的程序也只会在单核上按代码顺序依次执行,根本不用考虑太多. 后来,随着技术的发展,cpu的执行速度和内 ...

  8. Java内存模型与GC

    Java内存模型 JVM Spec中的Runtime Data Area分为5个区域:pc register(PC寄存器).java stack(JVM方法栈).native stack(本地方法栈) ...

  9. 从底层吃透java内存模型(JMM)、volatile、CAS

    前言 随着计算机的飞速发展,cpu从单核到四核,八核.在2020年中国网民数预计将达到11亿人.这些数据都意味着,作为一名java程序员,必须要掌握多线程开发,谈及多线程,绕不开的是对JMM(Java ...

最新文章

  1. Vue中使用moment将时间戳数据格式化显示(el-table中)
  2. GIF图片合集(用于网络请求图片用)
  3. 全国计算机等级考试题库二级C操作题100套(第47套)
  4. 网站常见问题1分钟定位(三)| 如何使用阿里云ARMS轻松重现用户浏览器问题
  5. 传闻中“日进斗金”的程序员,你真的了解吗?看完还想当程序员?
  6. asp.net 2.0 下的一个小技巧
  7. 你看过最好的心理学书籍是什么?
  8. linux未找到make命令,linux中无make命令的问题(make: *** 没有指明目标并且找不到 makefile及make命令安装方法)...
  9. MySQL学习笔记:limit
  10. laydate组件 无法传值_Vue组件间通信几种方式,你用哪种?【实践】
  11. asp.net的10个提升性能或扩展性的秘密(一)
  12. 单机:Oracle 19C 数据库一键安装
  13. SpringBoot 整合 kaptcha + redis 实现 图形验证码登录
  14. c语言求m n最小公倍数,最大公因数和最小公倍数的求法 求mn的最大公约数C语言...
  15. JDK的可视化工具——Java监视与管理控制台(JConsole)。
  16. 【转载】Linux摄像头驱动1——vivid
  17. 虚拟摄像头/无人直播效果分析,可替抖音/微信
  18. vue-pdf vue中导入文件 并预览
  19. HBuilder开发旅游类APP(三) ----- 给APP添加底部导航栏(底部选项卡)
  20. 林肯公园跑步歌单:摇滚助力跑出一道光

热门文章

  1. echart的x换行
  2. HDU6156 Palindrome Function
  3. C#流对象使用完后不立即释放的问题
  4. oracle按某个字段分组然后从每组取出最大的一条纪录
  5. iOS开发之 几本书
  6. “乘客迟到5分钟,滴滴司机无责取消订单”是一个好策略吗?
  7. 高级PM分析足记的成长周期,你的产品距离火爆还有多久?
  8. O2O产品经理,请多关注屏幕之外
  9. kali下Wreckuests | DDOS Atacks With HTTP-Flood
  10. 01-MPLS产生的背景/以及和其他技术比较的优势