Java内存模型_基础
线程之间的通信机制有两种:
1、共享内存:线程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式的通信。
2、消息传递:线程之间没有公共状态,线程之间必须发送消息来显示的进行通信
同步:是指程序中用于控制不同线程间操作发生相对顺序的机制。
在共享内存并发模型里,同步是显式进行的。程序员必须显式指定某个方法或某段代码需要在线程之间互斥执行。在消息传递的并发模型里,由于消息的发送必须在消息的接收之前,因此同步是隐式进行的。
Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式进行
在java中,所有实例域、静态域和数组元素存储在堆内存中,堆内存在线程之间共享。局部变量,方法定义参数和异常处理器参数不会在线程之间共享,它们不会有内存可见性问题,也不受内存模型的影响
内存不可见:是用于共享变量的值,没有及时刷新到主内存当中
Java内模型抽象结构示意图,如下

线程A与线程B之间要通信的话,必须要经历下面两个步骤。
1、首先,线程A把本地内存A中更新过的共享变量刷新到主内存中去。
2、然后,线程B到主内存中去读取线程A之前已更新过的共享变量。
这两个步骤实质上是线程A在向线程B发送消息,而且这个通信过程必须要经过主内存。JMM通过控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证。
写缓冲区:它可以保证指令流水线持续运行,它可以避免由于处理器停顿下来等待向内存写入数据而产生的延迟
处理器上的写缓存区,仅仅对它所在的处理器可见。这对内存操作的执行顺序产生重要的影响:处理器对内存的读/写操作的执行顺序,不一定与内存实际发生的读/写操作顺序一致

从内存操作实际发生的顺序来看,直到处理器A执行A3来刷新自己的写缓存区,写操作A1才算真正执行了。虽然处理器A执行内存操作的顺序为:A1->A2,但内存操作实际发生的顺序却是:A2->A1。此时,
处理器A的内存操作顺序被重排序了
为了保证内存可见性,java编译器在生成指令序列的适当位置会插入内存屏障指令来禁止特定类型的处理器重排序。JMM把内存屏障指令分为下列四类:
| 屏障类型 | 指令示例 | 说明 |
| LoadLoad Barriers | Load1; LoadLoad; Load2 | 确保Load1数据的装载,之前于Load2及所有后续装载指令的装载。 |
| StoreStore Barriers | Store1; StoreStore; Store2 | 确保Store1数据对其他处理器可见(刷新到内存),之前于Store2及所有后续存储指令的存储。 |
| LoadStore Barriers | Load1; LoadStore; Store2 | 确保Load1数据装载,之前于Store2及所有后续的存储指令刷新到内存。 |
| StoreLoad Barriers | Store1; StoreLoad; Load2 | 确保Store1数据对其他处理器变得可见(指刷新到内存),之前于Load2及所有后续装载指令的装载。StoreLoad Barriers会使该屏障之前的所有内存访问指令(存储和装载指令)完成之后,才执行该屏障之后的内存访问指令。 |
StoreLoad Barriers是一个“全能型”的屏障,它同时具有其他三个屏障的效果。现代的多处理器大都支持该屏障(其他类型的屏障不一定被所有处理器支持)。执行该屏障开销会很昂贵,因为当前处理器通常
要把写缓冲区中的数据全部刷新到内存中。
happens-before:在JMM中,如果一个操作需要对另外一个操作可见,那么这两个操作(可以在同一个线程之内,也可以不在同一个线程之内)之间必须要存在happens-before关系。
happens-before规则:
- 程序顺序规则:一个线程中的每个操作,happens- before 于该线程中的任意后续操作。
- 监视器锁规则:对一个监视器锁的解锁,happens- before 于随后对这个监视器锁的加锁。
- volatile变量规则:对一个volatile域的写,happens- before 于任意后续对这个volatile域的读。
- 传递性:如果A happens- before B,且B happens- before C,那么A happens- before C。
两个操作之间具有happens-before关系,并不意味着前一个操作必须要在后一个操作之前执行!happens-before仅仅要求前一个操作(执行的结果)对后一个操作可见,且前一个操作按顺序排在第二个操作之前。
有了这些基础之后,我们在继续往下分析
Java内存模型_基础的更多相关文章
- Java内存模型的基础
Java内存模型的基础 并发编程模型的两个关键问题 在并发编程中,需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来交换信息.在 ...
- Java内存模型_顺序一致性
数据竞争: 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据竞争的定义如下: 在一个线程中写一个变量 在另一个线程读同一个变量 而且写和读没有通过同步来排序 如果程序是正确同步的,程序 ...
- Java内存模型_重排序
重排序:是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段 1..编译器优化的重排序.编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序. 2..指令级并行的重排序.现 ...
- Java内存模型基础
Java内存模型的基础 并发编程模型的两个关键问题 在并发编程种,需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来交换信息.在 ...
- (第三章)Java内存模型(上)
一.java内存模型的基础 1.1 并发编程模型的两个关键问题 在并发编程中,需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来 ...
- 全面理解Java内存模型
尊重原创:http://blog.csdn.net/suifeng3051/article/details/52611310 Java内存模型即JavaMemory Model,简称JMM.JMM定义 ...
- 《Java并发编程的艺术》Java内存模型(三)
Java内存模型 一.Java内存模型的基础 1.并发编程模型的两个关键问题: 两个关键问题,线程之间如何通信和如何同步.两种方式,共享内存和消息传递.Java里线程的通信是通过共享内存,线程的同步是 ...
- Java并发编程(五)-- Java内存模型补充
前面我们已经介绍了:当对象和变量存储到计算机的各个内存区域时,必然会遇到的两个问题及解决方法 共享对象的可见性-- 解决方法:使用java volatile关键字 共享对象的竞争现象 -- 解决方法: ...
- Java并发编程(1)-Java内存模型
本文主要是学习Java内存模型的笔记以及加上自己的一些案例分享,如有错误之处请指出. 一 Java内存模型的基础 1.并发编程模型的两个问题 在并发编程中,需要了解并会处理这两个关键问题: 1.1.线 ...
随机推荐
- (转)java.util.Scanner应用详解
java.util.Scanner应用详解 java.util.Scanner是Java5的新特征,主要功能是简化文本扫描.这个类最实用的地方表现在获取控制台输入,其他的功能都很鸡肋,尽管Java ...
- mvc 下的 signalR使用小结
https://my.oschina.net/u/867090/blog/123474
- 使用Fiddler调试手机端页面请求/抓包
简介 Fiddler作为一个强大的抓包工具,也是非常强大的http(s)协议分析工具,我们通常用它跟踪请求,PC端使用这里暂不做介绍(这里前提是熟悉PC端的使用),使用很简单. 那么我们如何来用它来跟 ...
- PHP中使用单双引号的区别
1,双引号可以解析变量,单引号不可以解析: 2,双引号解析转义字符,单引号不解析转义,但是可以解析 \' 和 \\ ; 3,单双引号不能自己套自己,要嵌套使用,避免混乱: 4,单引号效率更高,能使 ...
- iOS耗电量测试
iOS耗电量测试 本文主要介绍的是使用Energy Diagnostics Instruments来进行iOS耗电量测试. 一.使用方法: 1)iOS 设置选项 ->开发者选项 ->log ...
- jquery实现多条件筛选特效代码分享
本文实例讲述了jquery实现多条件筛选特效.分享给大家供大家参考.具体如下:jquery实现的多条件搜索表单带日期选择表格表单效果源码,是一段实现了多个条件筛选搜索的特效代码,多条件拥有时间.地点. ...
- linux指令大全
系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS ...
- idea如何添加外部jar包
假设我们要将G:\ModuleAPI_Java_2.2.0.0 .jar导入工程中: 首先,在mvn命令行执行下面命令: mvn install:install-file -Dfile=G:\Modu ...
- Andrew Ng机器学习课程笔记(五)之应用机器学习的建议
Andrew Ng机器学习课程笔记(五)之 应用机器学习的建议 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7368472.h ...
- 前端到后台ThinkPHP开发整站(5)
今天周五了,这个项目做了五个晚上了,明天周末不用上班有一整天的时间来结束这个项目了,今晚主要把后台界面给弄出来了. 大概的整个后台界面就是这个样子了,接下来的工作就是搬砖了,一个个菜单功能填上去就是了 ...