聊聊JMM
JMM是什么?
JMM 全称 Java memory model ,直译过来就是Java内存模型,这里注意了,指到并不是JVM中的内存分布新生代、老年代、永久代这些,当然也不是 程序计数器(PC)、java虚拟机栈、本地方法栈、java堆、方法区。
那么它到底是什么呢?
内存模型
简单来说,JMM定义了线程和主内存之间的抽象关系 ,说到内存模型,我们可以顺便了解一下其他的内存模型 ,顺序一致性模型(理论模型),处理器的内存模型。(从另一个角度看JMM屏蔽了不同处理器内存模型的差异)
回到正题,要说清楚线程和主内存之间的抽象关系,先从线程的主要两个问题说起,如何通信和何时同步。
如何通信
如何通信指的是,线程之间用何种机制来交换信息, 现在存在的有两种,一种是隐式共享内存,另一种是通过显示发送消息。这里JMM使用的第一种(会存在本地写缓冲区和共享内存可见性问题),具体的实现可以看下图。
(好了你别说了,我是图)
何时同步
何时同步指的是,线程之间控制发生相对顺序的机制,为什么需要控制相对顺序的机制呢?(还记得我们上面说的顺序一致性模型吗,自行了解一下),这里主要是一种叫重排序的东西存在。
重排序
你或许又会说重排序是干嘛的,对我们有什么影响,这里简单的说,就是程序可能不会按照我们预期的方式执行,在单线程的情况下还好(因为有依赖保证、和as-if-serial),但在多线程但情况下就会出现各种奇奇怪怪的问题啦。
我们都知道,从java代码,经过编译成为.class字节码文件,再由不同平台jvm解析成为机器语言(java并不是解释型语言啊,JIT即时编译、Aot什么的)。 在这个过程中 编译器呀,处理器呀,内存模型啊,为了性能,在保证可靠性的前提下,会进行重排序。
那么为了让程序如我们所预期的方式执行,我们可以通过使用同步机制来完成。(如sync,lock,volatile,后面会稍微详细说说这几个的内存语义,映射到底层处理器其实就是使用内存屏障来防止重排序)

volatile语义
锁的内存语义
面向程序员和处理器编译器的happens-before
这些后面再说了orz,好了,mac没电了不说了
聊聊JMM的更多相关文章
- 聊聊CPU的LOCK指令
本文转载自聊聊CPU的LOCK指令 导语 在多线程操作中,可能最经常被提起的就是数据的可见性.原子性.有序性.不管是硬件方面.软件方面都在这三方面做了很足的工作,才能保证程序的正常运行. 之前发表过一 ...
- (五)JMM的介绍
1. JMM的介绍 在上一篇文章中总结了线程的状态转换和一些基本操作,对多线程已经有一点基本的认识了,如果多线程编程只有这么简单,那我们就不必费劲周折的去学习它了.在多线程中稍微不注意就会出现线程安全 ...
- Java并发(3)- 聊聊Volatile
引言 谈到volatile关键字,大多数开发者都有一定了解,可以说是开发者非常熟悉,深入之后又非常陌生的一个关键字.相当于轻量的synchronized,也叫轻量级锁,与synchronized相比性 ...
- Java内存模型(Java Memory Model,JMM)
今天简单聊聊什么叫做 Java 内存模型,不是 JVM 内存结构哦. JMM 是一个语言级别的内存模型,处理器的硬件模型是硬件级别,Java中的内存模型是内存可见性的基本保证.从而为我们 volati ...
- 聊聊高并发(十八)理解AtomicXXX.lazySet方法
看过java.util.concurrent.atomic包里面各个AtomicXXX类实现的同学应该见过lazySet方法.比方AtomicBoolean类的lazySet方法 public fin ...
- 每日三道面试题,通往自由的道路10——JMM篇
茫茫人海千千万万,感谢这一秒你看到这里.希望我的面试题系列能对你的有所帮助!共勉! 愿你在未来的日子,保持热爱,奔赴山海! 每日三道面试题,成就更好自我 今天我们还是继续聊聊多线程的一些其他话题吧! ...
- 聊聊Unity项目管理的那些事:Git-flow和Unity
0x00 前言 目前所在的团队实行敏捷开发已经有了一段时间了.敏捷开发中重要的一个话题便是如何对项目进行恰当的版本管理.项目从最初使用svn到之后的Git One Track策略再到现在的GitFlo ...
- Mono为何能跨平台?聊聊CIL(MSIL)
前言: 其实小匹夫在U3D的开发中一直对U3D的跨平台能力很好奇.到底是什么原理使得U3D可以跨平台呢?后来发现了Mono的作用,并进一步了解到了CIL的存在.所以,作为一个对Unity3D跨平台能力 ...
- fir.im Weekly - 聊聊 Google 开发者大会
中国互联网的三大错觉:索尼倒闭,诺基亚崛起,谷歌重返中国.12月8日,2016 Google 开发者大会正式发布了Google Developers 中国网站 ,包含了Android Develope ...
随机推荐
- [ZZ] NumPy 处理数据
NumPy-快速处理数据--ndarray对象--数组的创建和存取 https://www.cnblogs.com/moon1992/p/4946114.html NumPy-快速处理数据--ndar ...
- html5/h5课件如何制作?
随着flash逐渐被html5取代,很多教育机构都在面临着如何将自己的flash交互课件产品转换到html5版本的问题,最近遇到非常多的客户一上来就问我,flash课件能直接转成Html5课件么?答案 ...
- Apache Atlas元数据管理从入门到实战(1)
一.前言 元数据管理是数据治理非常重要的一个方向,元数据的一致性,可追溯性,是实现数据治理非常重要的一个环节.传统数据情况下,有过多种相对成熟的元数据管理工具,而大数据时代,基于hadoop,最为 ...
- RN 使用第三方字体
Android: 程序会尝试在 assets/fonts 目录下查找字体文件,如果没找到会使用默认的字体 所以将文件放到路径下才能生效! [project root]/android/app/src/ ...
- Struts2多文件上传原理和示例
一.创建上传文件的页面,代码如下所示 1.Struts2也可以很方便地实现多文件上传. 在输入表单域增加多个文件域:multifileupload.jsp <%@ page lan ...
- Caching in Presto
转自:Caching in Presto Qubole’s Presto-as-a-Service is primarily targeted at Data Analysts who are tas ...
- MFC 编辑框输入16进制字符串转换为16进制数或者10进制数据计算
1.编辑框添加变量,并选择变量类型为CString. 2. 使用“_tcstoul”函数将Cstring 类型转换为16进制/10进制数进行计算.
- Docker使用Link与newwork在容器之间建立连接
一,使用 --link容器互联 docker 默认使允许container 互通的(通过-icc=false 关闭互通)同一个宿主机上的多个docker容器之间如果想进行通信,可以通过使用容器的ip地 ...
- Collection 和 Collections的区别。(转)
Collection 和 Collections的区别. Collections是个java.util下的类,它包含有各种有关集合操作的静态方法. Collection是个java.util下的接口, ...
- Mock及Mockito使用
mockito http://www.vogella.com/tutorials/Mockito/article.html 原文地址: http://www.open-open.com/lib/vie ...