(转载)java内存模型
java并发采用的是共享内存模型,线程之间的通信对程序员来说是透明的,内存可见性问题很容易困扰着java程序员,今天我们就来揭开java内存模型的神秘面纱。
在揭开面纱之前,我们需要认识几个基础概念:内存屏障(memory Barriers),指令重排序,happens-before规则,as-if-serial语义。
什么是 Memory Barrier(内存屏障)?
内存屏障,又称内存栅栏,是一个CPU指令,基本上它是一条这样的指令:
1、保证特定操作的执行顺序。
2、影响某些数据(或则是某条指令的执行结果)的内存可见性。
编译器和CPU能够重排序指令,保证最终相同的结果,尝试优化性能。插入一条Memory Barrier会告诉编译器和CPU:不管什么指令都不能和这条Memory Barrier指令重排序。
Memory Barrier所做的另外一件事是强制刷出各种CPU cache,如一个 Write-Barrier(写入屏障)将刷出所有在 Barrier 之前写入 cache 的数据,因此,任何CPU上的线程都能读取到这些数据的最新版本。
这和java有什么关系?volatile是基于Memory Barrier实现的。
如果一个变量是volatile修饰的,JMM会在写入这个字段之后插进一个Write-Barrier指令,并在读这个字段之前插入一个Read-Barrier指令。
这意味着,如果写入一个volatile变量a,可以保证:
1、一个线程写入变量a后,任何线程访问该变量都会拿到最新值。
2、在写入变量a之前的写入操作,其更新的数据对于其他线程也是可见的。因为Memory Barrier会刷出cache中的所有先前的写入。
happens-before
从jdk5开始,java使用新的JSR-133内存模型,基于happens-before的概念来阐述操作之间的内存可见性。
在JMM中,如果一个操作的执行结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系,这个的两个操作既可以在同一个线程,也可以在不同的两个线程中。
与程序员密切相关的happens-before规则如下:
1、程序顺序规则:一个线程中的每个操作,happens-before于该线程中任意的后续操作。
2、监视器锁规则:对一个锁的解锁操作,happens-before于随后对这个锁的加锁操作。
3、volatile域规则:对一个volatile域的写操作,happens-before于任意线程后续对这个volatile域的读。
4、传递性规则:如果 A happens-before B,且 B happens-before C,那么A happens-before C。
注意:两个操作之间具有happens-before关系,并不意味前一个操作必须要在后一个操作之前执行!仅仅要求前一个操作的执行结果,对于后一个操作是可见的,且前一个操作按顺序排在后一个操作之前。
指令重排序
在执行程序时,为了提高性能,编译器和处理器会对指令做重排序。但是,JMM确保在不同的编译器和不同的处理器平台之上,通过插入特定类型的Memory Barrier来禁止特定类型的编译器重排序和处理器重排序,为上层提供一致的内存可见性保证。
1、编译器优化重排序:编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。
2、指令级并行的重排序:如果不存l在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。
3、内存系统的重排序:处理器使用缓存和读写缓冲区,这使得加载和存储操作看上去可能是在乱序执行。
数据依赖性
如果两个操作访问同一个变量,其中一个为写操作,此时这两个操作之间存在数据依赖性。
编译器和处理器不会改变存在数据依赖性关系的两个操作的执行顺序,即不会重排序。
as-if-serial
不管怎么重排序,单线程下的执行结果不能被改变,编译器、runtime和处理器都必须遵守as-if-serial语义。
抽象结构
java线程之间的通信由java内存模型(JMM)控制,JMM决定一个线程对共享变量(实例域、静态域和数组)的写入何时对其它线程可见。
从抽象的角度来看,JMM定义了线程和主内存Main Memory(堆内存)之间的抽象关系:线程之间的共享变量存储在主内存中,每个线程都有自己的本地内存Local Memory(只是一个抽象概念,物理上不存在),存储了该线程的共享变量副本。
所以,线程A和线程B之前需要通信的话,必须经过一下两个步骤:
1、线程A把本地内存中更新过的共享变量刷新到主内存中。
2、线程B到主内存中读取线程A之前更新过的共享变量。
转载自:http://www.jianshu.com/p/d3fda02d4cae
(转载)java内存模型的更多相关文章
- JVM学习(3)——总结Java内存模型---转载自http://www.cnblogs.com/kubixuesheng/p/5202556.html
俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 为什么学习Java的内存模式 缓存一致性问题 什么是内存模型 JMM(Java Memory Model)简 ...
- 深入理解 Java 内存模型(转载)
摘要: 原创出处 http://www.54tianzhisheng.cn/2018/02/28/Java-Memory-Model/ 「zhisheng」欢迎转载,保留摘要,谢谢! 0. 前提 &l ...
- 【Todo】【转载】深入理解Java内存模型
提纲挈领地说一下Java内存模型: 什么是Java内存模型 Java内存模型定义了一种多线程访问Java内存的规范.Java内存模型要完整讲不是这里几句话能说清楚的,我简单总结一下Java内存模型的几 ...
- Java内存模型(转载)
1. 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标之一.一般衡量一个服务器性能的高低好坏,使用每秒事务处理数(Transactions Per Second,TPS)这个指标比较能说明问题 ...
- 全面理解Java内存模型(JMM)及volatile关键字(转载)
关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoad ...
- Java 内存模型及GC原理 (转载)
一个优秀Java程序员,必须了解Java内存模型.GC工作原理,以及如何优化GC的性能.与GC进行有限的交互,有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只有全面提升内存的管理效率,才能 ...
- Java 理论与实践: 修复 Java 内存模型,第 2 部分(转载)
在 JSR 133 中 JMM 会有什么改变? 活跃了将近三年的 JSR 133,近期发布了关于如何修复 Java 内存模型(Java Memory Model, JMM)的公开建议.在本系列文章的 ...
- 什么是 Java 内存模型,最初它是怎样被破坏的?(转载)
活跃了将近三年的 JSR 133,近期发布了关于如何修复 Java 内存模型(Java Memory Model, JMM)的公开建议.原始 JMM 中有几个严重缺陷,这导致了一些难度高得惊人的概念语 ...
- Java内存模型(转载)
本文章节: 1.JMM简介 2.堆和栈 3.本机内存 4.防止内存泄漏 1.JMM简介 i.内存模型概述 Java平台自动集成了线程以及多处理器技术,这种集成程度比Java以前诞生的计算机语言要厉害很 ...
随机推荐
- SystemUI中设置横竖屏显示
SystemUI中快捷菜单有 “方向锁定” . RotationLockTile protected void handleClick() { if (mController == null) ret ...
- quartz一次简单应用经历
项目里使用到每月的第一天需要定时统计上一个月的某种数据,这个时候,我开始第一次知道任务调度这么一个专业词汇.也初次了解quartz这个任务调度框架.网上看了好几篇博文,有种quartz越看越难的感觉, ...
- xml中CDATA包含问题
最近对接徐州一家医院,his是东联的,其中有个接口要求传入格式类似于 : <![CDATA[ <Request> <CardNo>000002629518</Car ...
- Oracle 12c 安装问题及解决方案
1. 介绍 今天在我的开发电脑上安装Oracle12c,电脑环境是windows10家庭中文版,安装的Oracle数据库版本Oracle(12.1.0.2.0) - Standard Edition ...
- git撤销commit-hard
场景: 不小心commit了一个不应该commit的修改,但是还没有push,想撤销那个commit 命令: a)git log b)git reset --hard commit_id 具体步骤如下 ...
- PhpSpreadsheet处理表格
介绍:PhpSpreadsheet是PHPExcel的下一个版本.它打破了兼容性,大大提高了代码库质量(命名空间,PSR合规性,最新PHP语言功能的使用等).由于所有努力都转移到了PhpSpreads ...
- GXB动态重配置
可选择重配置逻辑(Optional Reconfiguration Logic) 使能选项: • Capability registers • Control and status registers ...
- java开发师笔试面试每日12题(3)
1.JDK和JRE的区别是什么? Java运行时环境(JRE)是将要执行Java程序的Java虚拟机.它同时也包含了执行applet需要的浏览器插件.Java开发工具包(JDK)是完整的Java软件开 ...
- Android逆向破解表单注册程序
Android逆向破解表单注册程序 Android开发 ADT: android studio(as) 程序界面如下,注册码为6位随机数字,注册成功时弹出通知注册成功,注册失败时弹出通知注册失败. 布 ...
- charming_memory
Memory Master 一 .Forget遗忘 遗忘似乎是记忆的天敌,但是善用遗忘规律却能帮助我们更好的记忆. 复习的最佳时间是实际材料的1~24小时,最晚不超过2天,复习时间太长,就有一种生疏的 ...