Java内存模型_顺序一致性
数据竞争:
当程序未正确同步时,就会存在数据竞争。java内存模型规范对数据竞争的定义如下:
- 在一个线程中写一个变量
- 在另一个线程读同一个变量
- 而且写和读没有通过同步来排序
如果程序是正确同步的,程序的执行将具有顺序一致性–即程序的执行结果与该程序在顺序一致性内存模型中的执行结果相同
顺序一致性内存模型:
顺序一致性内存模型是一个被计算机科学家理想化了的理论参考模型,它为程序员提供了极强的内存可见性保证。顺序一致性内存模型有两大特性:
- 一个线程中的所有操作必须按照程序的顺序来执行。
- (不管程序是否同步)所有线程都只能看到一个单一的操作执行顺序。在顺序一致性内存模型中,每个操作都必须原子执行且立刻对所有线程可见。
同步程序员的顺序一致性结果
JMM在具体实现上的基本方针:在不改变(正确同步的)程序执行结果的前提下,尽可能的为编译器和处理器的优化打开方便之门。
未同步程序的执行特性
对于未同步或未正确同步的多线程程序,JMM只提供最小安全性:线程执行时读取到的值,要么是之前某个线程写入的值,要么是默认值(0,null,false),JMM保证线程读操作读取到的值不会无中生有的
冒出来。为了实现最小安全性,JVM在堆上分配对象时,首先会清零内存空间,然后才会在上面分配对象(JVM内部会同步这两个操作)。因此,在以清零的内存空间分配对象时,域的默认初始化已经完成
了。JMM不保证未同步程序的执行结果与该程序在顺序一致性模型中的执行结果
和顺序一致性模型一样,未同步程序在JMM中的执行时,整体上也是无序的,其执行结果也无法预知。同时,未同步程序在这两个模型中的执行特性有下面几个差异:
1、顺序一致性模型保证单线程内的操作会按程序的顺序执行,而JMM不保证单线程内的操作会按程序的顺序执行(比如上面正确同步的多线程程序在临界区内的重排序)。这一点前面已经讲过了,这里就不再赘述。
2、顺序一致性模型保证所有线程只能看到一致的操作执行顺序,而JMM不保证所有线程能看到一致的操作执行顺序。这一点前面也已经讲过,这里就不再赘述。
3、JMM不保证对64位的long型和double型变量的读/写操作具有原子性,而顺序一致性模型保证对所有的内存读/写操作都具有原子性。
第3个差异与处理器总线的工作机制密切相关。在计算机中,数据通过总线在处理器和内存之间传递。每次处理器和内存之间的数据传递都是通过一系列步骤来完成的,这一系列步骤称之为总线事务。总线事
务包括读事务和写事务。读事务从内存传送数据到处理器,写事务从处理器传送数据到内存,每个事务会读/写内存中一个或多个物理上连续的字。这里的关键是,总线会同步试图并发使用总线的事务。在一
个处理器执行总线事务期间,总线会禁止其它所有的处理器和I/O设备执行内存的读/写。下面让我们通过一个示意图来说明总线的工作机制:

如上图所示,假设处理器A,B和C同时向总线发起总线事务,这时总线仲裁会对竞争作出裁决,这里我们假设总线在仲裁后判定处理器A在竞争中获胜(总线仲裁会确保所有处理器都能公平的访问内存)。此
时处理器A继续它的总线事务,而其它两个处理器则要等待处理器A的总线事务完成后才能开始再次执行内存访问。假设在处理器A执行总线事务期间(不管这个总线事务是读事务还是写事务),处理器D向总
线发起了总线事务,此时处理器D的这个请求会被总线禁止。
总线的这些工作机制可以把所有处理器对内存的访问以串行化的方式来执行;在任意时间点,最多只能有一个处理器能访问内存。这个特性确保了单个总线事务之中的内存读/写操作具有原子性。
在一些32位的处理器上,如果要求对64位数据的写操作具有原子性,会有比较大的开销。为了照顾这种处理器,java语言规范鼓励但不强求JVM对64位的long型变量和double型变量的写具有原子性。当JVM
在这种处理器上运行时,会把一个64位long/ double型变量的写操作拆分为两个32位的写操作来执行。这两个32位的写操作可能会被分配到不同的总线事务中执行,此时对这个64位变量的写将不具有原子性。
当单个内存操作不具有原子性,将可能会产生意想不到后果。请看下面示意图:

如上图所示,假设处理器A写一个long型变量,同时处理器B要读这个long型变量。处理器A中64位的写操作被拆分为两个32位的写操作,且这两个32位的写操作被分配到不同的写事务中执行。同时处理器B中
64位的读操作被分配到单个的读事务中执行。当处理器A和B按上图的时序来执行时,处理器B将看到仅仅被处理器A“写了一半“的无效值。
注意,在JSR -133之前的旧内存模型中,一个64位long/ double型变量的读/写操作可以被拆分为两个32位的读/写操作来执行。从JSR -133内存模型开始(即从JDK5开始),
仅仅只允许把一个64位long/double型变量的写操作拆分为两个32位的写操作来执行,任意的读操作在JSR -133中都必须具有原子性(即任意读操作必须要在单个读事务中执行)。
Java内存模型_顺序一致性的更多相关文章
- Java内存模型_基础
线程之间的通信机制有两种: 1.共享内存:线程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式的通信. 2.消息传递:线程之间没有公共状态,线程之间必须发送消息来显示的进行通信 同步:是指程 ...
- Java内存模型_重排序
重排序:是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段 1..编译器优化的重排序.编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序. 2..指令级并行的重排序.现 ...
- Java 并发系列之三:java 内存模型(JMM)
1. 并发编程的挑战 2. 并发编程需要解决的两大问题 3. 线程通信机制 4. 内存模型 5. volatile 6. synchronized 7. CAS 8. 锁的内存语义 9. DCL 双重 ...
- Java内存模型深度解析:总结--转
原文地址:http://www.codeceo.com/article/java-memory-7.html 处理器内存模型 顺序一致性内存模型是一个理论参考模型,JMM和处理器内存模型在设计时通常会 ...
- java内存模型-总结
处理器内存模型 顺序一致性内存模型是一个理论参考模型,JMM 和处理器内存模型在设计时通常会把顺序一致性内存模型作为参照.JMM 和处理器内存模型在设计时会对顺序一致性模型做一些放松,因为如果完全按照 ...
- 深入理解Java内存模型(七)——总结
处理器内存模型 顺序一致性内存模型是一个理论参考模型,JMM和处理器内存模型在设计时通常会把顺序一致性内存模型作为参照.JMM和处理器内存模型在设计时会对顺序一致性模型做一些放松,因为如果完全按照顺序 ...
- 【转】深入理解Java内存模型(七)——总结
处理器内存模型 顺序一致性内存模型是一个理论参考模型,JMM和处理器内存模型在设计时通常会把顺序一致性内存模型作为参照.JMM和处理器内存模型在设计时会对顺序一致性模型做一些放松,因为如果完全按照顺序 ...
- (第三章)Java内存模型(下)
一.happens-before happens-before是JMM最核心的概念.对于Java程序员来说,理解happens-before是理解JMM的关键. 1.1 JMM的设计 从JMM设计者的 ...
- java内存模型7-处理器内存模型
处理器内存模型 顺序一致性内存模型是一个理论参考模型,JMM和处理器内存模型在设计时通常会把顺序一致性内存模型作为参照.JMM和处理器内存模型在设计时会对顺序一致性模型做一些放松,因为如果完全按照顺序 ...
随机推荐
- Unity 工作经历+近期面试经历
由于团队解散,这最近都在找新工作机会--投简历找工作.已经面试三家了,都没拿到offer,挺失落的.把这种感受记录下来,以作后鉴. 这本质上是一篇面试经历的记录,并不是什么面试攻略,主要是给自己总结的 ...
- 四.GC —三分钟认识JAVA回收机制(Java Garbage Collection)
这里以jdk1.8做讲解.Jdk1.8的分代去掉了永久代,只分为新生代(有的也译为年轻代)和年老代. 名词解释: 系统吞吐量:用于处理应用程序处理事务的线程数与用于GC的线程数的比. pause ti ...
- vue-项目入门
初入前端的新人在碰到vue.js后,去过官网,估计粗略的看下api文档以后会以为vue的安装只是把那串js代码直接粘贴复制到文档即可,虽然这样是可以,但那在项目中并不合适. 项目中的vue引入(配制安 ...
- 框架 之 -------Spring
目录一.Spring工作原理 二.为什么要用Spring三.请你谈谈SSH整合四.介绍一下Spring的事务管理五.什么是依赖注入,依赖注入的作用是什么? 六.什么是AOP,AOP的作用是什么? 七. ...
- git push解决办法: ! [remote rejected] master -> master (pre-receive hook declined)
前天准备上传一个project到GitLab上,但是试了很多次都上传不上去,报错如下: ! [remote rejected] master -> master (pre-receive hoo ...
- Java基础之集合框架类及泛型简介
Collection接口 Collection 通用的常见方法 add()添加一个元素,可以指定脚标 addAll()将一个collection放入 clear()清除 remove()删除元素,返回 ...
- 11. leetcode 283. Move Zeroes
Given an array nums, write a function to move all 0's to the end of it while maintaining the relativ ...
- 玛雅游戏[NOIP2011]
题目描述 Mayan puzzle 是最近流行起来的一个游戏.游戏界面是一个7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...
- 压缩[SCOI2007]
题目描述 给一个由小写字母组成的字符串,我们可以用一种简单的方法来压缩其中的重复信息.压缩后的字符串除了小写字母外还可以(但不必)包含大写字母R与M,其中M标记重复串的开始,R重复从上一个M(如果当前 ...
- Oracle sql 查询结果某一列字段合并成为一条数据
使用oracle中自带函数 wmsys.wm_concat(需合并列的字段名) 用法如下: select code,name,wmsys.wm_concat(baname) from tab gro ...