JMM

Java Memory Model,Java内存模型,属于语言级的内存模型

并发编程中存在的问题:

  • 如何通信:用于线程之间交换信息。两种方式:共享内存,消息传递
  • 如何同步:用于控制不同线程间操作发生的相对顺序。共享内存的同步是显式的,消息传递的同步是隐式的,因为消息发送必须在消息接受之前,已经隐式包含了这个顺序关系

Java并发采用的是共享内存模型,内存模型的抽象结构如下图:

线程A和线程B通信的两个步骤:

  1. 线程A把本地内存中更新过的共享变量刷新到主内存中去
  2. 线程B去主内存中读取线程A之前更新过的共享变量

    JMM通过控制主内存和线程的本地内存之间的交互,来为程序提供内存可见性的保证

重排序

在执行程序时,为了提高性能,编译器处理器会对指令做重排序,包括以下三类:

  1. 编译器在不改变单线程语意的前提下对语句执行顺序的优化
  2. 处理器对不存在数据依赖性的语句,改变语句对应指令的执行顺序
  3. 内存系统的重排序

也就是说从Java源码到实际执行的指令序列经历了:

源代码——>编译器优化——>处理器优化——>内存系统重排序——>实际执行的指令序列

上述重排序都可能导致内存可见性问题

JMM属于语言级内存模型,在不同的编译器(软件)和不同的处理器平台(硬件)之上,通过以下方法保证一致的内存可见性:

  1. JMM的重排序规则禁止特定编译器的编译成排序
  2. JMM的处理器重排序规则会要求编译器在生成指令序列时,插入特定的内存屏障(Memory Barriers)指令

以上JMM的各种禁止重排序的规则和实现确保了happens-before

happens-before

基本原则

在保证执行结果正确的前提下尽可能提高执行的并行度

定义

  • 如果A操作happens-before B,那么操作A的结果一定对操作B可见,而且操作A的执行顺序一定排在操作B前面(面向程序员:向程序员保证内存可见性)
  • 两个操作存在happens-before关系,并不意味着Java平台的具体实现必须按照happens-before关系指定的顺序执行,只要保证执行结果正确JMM允许重排序(面向编译器和处理器:保证结果正确的前提下尽可能的优化并发性能)

规则

  1. 程序顺序规则:一个线程中每一个操作,happens-before于该线程所有后续操作
  2. 监视器锁规则:对于一个锁的解锁,happnes-before于对同一个锁的加锁
  3. volatile规则:对于volatile域的写,happens-before于任意后续对这个域的读
  4. 传递性规则:如果A happens-before于B,B happens-before于C,那么A happens-before于C
  5. start()规则:如果线程A执行ThreadB.start()操作,那么线程ThreadB.start()操作happens-before于ThreadB的任何操作
  6. join()规则:如果线程A执行ThreadB.join()操作并成功返回,那么ThreadB的任何操作happens-before于线程A从ThreadB.join()成功返回

写缓冲区

现代处理器使用写缓冲区临时保存向主存写入的数据,可以避免由于处理器向主存中写入数据而产生的延迟(对内存的读写速度远慢于处理器运行速度,对寄存器或者缓存的读写速度快于对)

数据依赖

JMM的重排序规则只会保证单线程的数据依赖正确

JMM只保证正确同步的并发操作是正确的(和顺序一致内存模型得到的结果相同)

顺序一致性内存模型

  • 理想模型
  • 一个线程中所有操作必须 按照程序顺序执行
  • 每个操作原子执行,并且对所有线程立即可见(实际情况:没有原子执行,因为缓存也不能立即可见),因为立即可见,所以整体上所有线程看到的都是一个单一的执行顺序

Java 线程 — JMM Java内存模型的更多相关文章

  1. Java虚拟机学习 - 体系结构 内存模型

    一:Java技术体系模块图 二:JVM内存区域模型 1.方法区 也称"永久代” .“非堆”, 它用于存储虚拟机加载的类信息.常量.静态变量.是各个线程共享的内存区域.默认最小值为16MB,最 ...

  2. Java虚拟机学习 - 体系结构 内存模型(1)

    一:Java技术体系模块图 二:JVM内存区域模型 1.方法区 也称"永久代" ."非堆",  它用于存储虚拟机加载的类信息.常量.静态变量.是各个线程共享的内 ...

  3. Java虚拟机学习 - 体系结构 内存模型(转载)

    一:Java技术体系模块图 二:JVM内存区域模型 1.方法区 也称"永久代” .“非堆”,  它用于存储虚拟机加载的类信息.常量.静态变量.是各个线程共享的内存区域.默认最小值为16MB, ...

  4. Java:JVM的内存模型

    JVM内存模型 JVM内存模型可以分为两个部分,如下图所示,堆和方法区是所有线程共有的,而虚拟机栈,本地方法栈和程序计数器则是线程私有的.   1. 堆(Heap) 堆内存是所有线程共有的,可以分为两 ...

  5. java中JVM虚拟机内存模型详细说明

    java中JVM虚拟机内存模型详细说明 2012-12-12 18:36:03|  分类: JAVA |  标签:java  jvm  堆内存  虚拟机  |举报|字号 订阅     JVM的内部结构 ...

  6. 【java虚拟机】jvm内存模型

    作者:pengjunlee原文链接:https://blog.csdn.net/pengjunlee/article/details/71909239 目录 一.运行时数据区域 1.程序计数器 2.J ...

  7. 第23章 java线程通信——生产者/消费者模型案例

    第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...

  8. 【Java线程】Java内存模型总结

    学习资料:http://www.infoq.com/cn/articles/Java-memory-model-1 Java的并发采用的是共享内存模型(而非消息传递模型),线程之间共享程序的公共状态, ...

  9. (转)【Java线程】Java内存模型总结

    Java的并发采用的是共享内存模型(而非消息传递模型),线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信.多个线程之间是不能直接传递数据交互的,它们之间的交互只能通过共享变 ...

随机推荐

  1. ORA-01439: column to be modified must be empty to change datatype

    修改数据库字段类型,但是由于数据表已经存在数据,无法修改: 显示错误:  写道 ORA-01439: column to be modified must be empty to change dat ...

  2. 技术英文单词贴--B

    B breadcrumb 面包屑 bubble 冒泡

  3. 图解 & 深入浅出 JavaWeb:Servlet必会必知

    从[JavaEE 要懂的小事] Http相关,一直想写点Web开发相关的.最近项目接口开发紧,还有准备新的九月份战斗.JDK IO源码就隔一段落,温故知新看看Servlet & JSP 相关. ...

  4. js判断用户是否禁用了cookie

    function CookieEnable() { var result = false; if (navigator.cookiesEnabled) return true; document.co ...

  5. CWebBrowser2获取html的内容

    m_web为浏览器控件的变量名 LPDISPATCH p=m_web.GetDocument(); CComQIPtr<IHTMLDocument2,&IID_IHTMLDocument ...

  6. 20145225 《Java程序设计》 第3周学习总结

    20145225<Java程序设计> 第3周学习总结 教材学习内容总结 4.1类与对象 相当于设计图纸,用"new"创建的对象,就是依据设计图做成的成品 . 例(定义C ...

  7. android4.3 Bluetooth(le)分析之startLeScan分析

    BluetoothAdapter.java中有low enery(le)的一些方法,android提供了这些方法,但源码中并未找到这些方法的调用之处.本文档主要分析这类方法的执行流程,来了解下le到底 ...

  8. (2015秋) 作业6:(电梯系统之结对编程 I 总分=2*50 分)

    电梯系统 0. 背景 南通大学钟秀校区“主教学楼” 用 2 部电梯(连地下室共9层):每到下课.上课前都特别拥挤,大家希望改进已有的电梯调度算法,满足学生和老师快速乘坐电梯的需要.因此,需要重新设计一 ...

  9. Oracle创建表(包含、主键自增)

    注意:Oracle导出建表语句不会导出触发器及自增索引 第一步:创建一张表 create table member( memberId number primary key, --主键.自增长 mem ...

  10. STL之map应用 +hash表(51nod 1095)

    题目:Anigram单词 题意:给出词典,再给出一些单词,求单词的Anigram数量. 思路:先将字串转换成哈希表,然后再用map链接. hash表构造方法汇总:http://www.cnblogs. ...