cpu指令重排序的原理
目录:
1.重排序场景
2.追根溯源
3.缓存一致性协议
4.重排序原因
一、重排序场景
class ResortDemo {
int a = 0;
boolean flag = false; public void writer() {
a = 1; //
flag = true; //
} Public void reader() {
if (flag) { //
int i = a * a; //
……
}
}
}
当两个线程 A 和 B,A 首先执行writer() 方法,随后 B 线程接着执行 reader() 方法。线程B在执行操作4时,能否看到线程 A 在操作1对共享变量 a 的写入?
答案是:不一定能看到。
由于操作1和操作2没有数据依赖关系,编译器和处理器可以对这两个操作重排序;同样,操作3和操作4没有数据依赖关系,编译器和处理器也可以对这两个操作重排序。
二、追根溯源
三、缓存一致性协议
据不一致
四、重排序原因
基于上图中的原因,CPU又引入了storeBuffers的缓冲区。CPU0 只需要在写入共享数据时,直接把数据写入到 storebufferes 中,同时发送 invalidate 消息,然后继续去处理其
这个时候,我们再来看上述标题一中的重排序场景。
class ResortDemo {
int a = 0;
boolean flag = false; public void writer() {
a = 1; //1
flag = true; //2
} Public void reader() {
if (flag) { //3
int i = a * a; //4
……
}
}
}
当执行1操作时,a的状态从S->M,此时,线程A会先把变更写入到storebuffers,然后发送invalidate去异步通知其他CPU线程,紧接着就执行了下面的2操作。
此时,可能1的变更还在storebuffers中,并未提交到主内存。什么时候会提交到主内存,也不确定。
所以,线程B调用read方法可能会出现,看到了flag的变更,但是看不到a的变更,就出现了重排序的现象。
cpu指令重排序的原理的更多相关文章
- CPU指令重排序与MESI缓存一致性
一.重排序场景 class ResortDemo { int a = 0; boolean flag = false; public void writer() { a = 1; //1 flag = ...
- java高并发核心要点|系列4|CPU内存指令重排序(Memory Reordering)
今天,我们来学习另一个重要的概念. CPU内存指令重排序(Memory Reordering) 什么叫重排序? 重排序的背景 我们知道现代CPU的主频越来越高,与cache的交互次数也越来越多.当CP ...
- Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)
一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...
- Java的多线程机制系列:(四)不得不提的volatile及指令重排序(happen-before)
一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...
- 深入浅出Java并发包—指令重排序
前面大致提到了JDK中的一些个原子类,也提到原子类是并发的基础,更提到所谓的线程安全,其实这些类或者并发包中的这么一些类,都是为了保证系统在运行时是线程安全的,那到底怎么样才算是线程安全呢? Java ...
- JVM并发机制的探讨——内存模型、内存可见性和指令重排序
并发本来就是个有意思的问题,尤其是现在又流行这么一句话:“高帅富加机器,穷矮搓搞优化”. 从这句话可以看到,无论是高帅富还是穷矮搓都需要深入理解并发编程,高帅富加多了机器,需要协调多台机器或者多个CP ...
- 深入浅出 Java Concurrency (4): 原子操作 part 3 指令重排序与happens-before法则
转: http://www.blogjava.net/xylz/archive/2010/07/03/325168.html 在这个小结里面重点讨论原子操作的原理和设计思想. 由于在下一个章节中会谈到 ...
- 轻松学JVM(二)——内存模型、可见性、指令重排序
上一篇我们介绍了JVM的基本运行流程以及内存结构,对JVM有了初步的认识,这篇文章我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存 ...
- 【java多线程系列】java内存模型与指令重排序
在多线程编程中,需要处理两个最核心的问题,线程之间如何通信及线程之间如何同步,线程之间通信指的是线程之间通过何种机制交换信息,同步指的是如何控制不同线程之间操作发生的相对顺序.很多读者可能会说这还不简 ...
随机推荐
- JavaWeb 之 JSTL 标签
JSTL 标签库 一.概述 1.概念 JSTL : JavaServer Pages Tag Library JSP标准标签库. 是由 Apache 组织提供的开源的免费的 jsp 标签. 2.作用 ...
- Mybatis自动生成代码,MyBatis Generator
这还是在学校里跟老师学到的办法,然后随便在csdn下载一个并调试到可以用的状态. 基本由这几个文件组成,一个mysql连接的jar包.一个用于自动生成的配置文件,一个自动生成的jar包,运行jar包语 ...
- 使用 shell 脚本配置 iOS 工程
APP开发过程中,往往需要在多个网络环境或配置中进行切换,以获取不同配置的APP,甚至有时需要用一套代码经过简单的配置生成不同的APP.而手动配置费时费力,且容易出错.这里介绍用脚本工具,去生成不 ...
- 个人项目—WC
一,Github地址:https://github.com/mushan520/WC.git 二.PSP表格: PSP2.1 Personal Software Process Stages 预估耗 ...
- day 07 预科
目录 异常处理 字符串内置方法 1.索引取值 2.切片 3.成员运算 4.for循环 5.len() 6.strip(): 默认去掉两端空格 7.lsteip()/rstrip(): 去左端/右端 空 ...
- Oracle 12cR1 RAC集群安装(二)--使用图形界面安装
Oracle 12cR1 RAC集群安装文档:Oracle 12cR1 RAC集群安装(一)--环境准备Oracle 12cR1 RAC集群安装(二)--使用图形界面安装Oracle 12cR1 RA ...
- 对 Jenkins+ANT+Jmeter 接口测试的实践
转载地址:https://testerhome.com/topics/5262 1.前言 最近感觉大家都在讲Jenkins+jmeter+ant或maven的使用,但没有说到具体怎么投入到项目使用,只 ...
- Mybatis容易遇到的问题
1.MyBatis中#和$的区别? 1.使用#的原理是?占位符,而$的原理为直接字符串拼接方式 2.$方式一般使用在写数据库中的固定字段时候才会使用例如表名或者列名(select * from use ...
- 获取国定字符的内容split
a="Time:20190822_111655_554 Start Cloud new case, Num=1, Input=/data/voice/20190725_035326_2_vo ...
- fitnesse的安装
最近项目组有个单独的功能模块需要写自动化,由于是测试接口,我本来是想用之前那个项目组使用的robot framework+python,但是呢,项目组领导觉得,目前项目开发语言是java,相应的自动化 ...