JVM学习(八)指令重排序
一、数据依赖性
在学习JVM的指令重排序之前,我们先了解一下什么是数据依赖性:
编译器和处理器在处理具体的指令时,可能会对操作进行重排序来提高执行性能【多条指令并行执行,所以提升性能的同时也可能会导致指令乱序】;而上面3种情况,只要重排序两个操作的执行顺序,程序的执行结果就会被改变。
编译器和处理器在重排序时,会遵守数据依赖性,编译器和处理器不会改变存在数据依赖关系的两个操作的执行顺序。
PS:这里所说的数据依赖性仅针对单个处理器中执行的指令序列和单个线程中执行的操作,不同处理器之间和不同线程之间的数据依赖性不被编译器和处理器考虑。
二、相关规则
as if serial语义
定义:不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不会改变。
解析:编译器、runtime和处理器都必须遵守as-if-serial语义。 为了遵守as-if-serial语义,编译器和处理器不会对存在数据依赖关系的操作做重排序,因为这种重排序会改变执行结果。 但是,如果操作之间不存在数据依赖关系,这些操作就可能被编译器和处理器重排序。
happen-before原则
定义:一个线程中的每一个操作happens-before于该线程的任意后续操作,这里的happens-before并不是前一个操作必须早于后一个操作, 而是前一个操作必须对后一个操作可见,否则不能重排序。
程序次序规则
定义:一段程序代码的执行在单个线程中看起来是有序的,不过因为虚拟机可能会对程序代码进行指令重排序,虽然进行重排序,但是最终执行的结果是与程序顺序执行的结果一致的。
三、重排序对多线程的影响
我们前面知道了,在单线程运行中,指令重排序不能影响程序执行的结果,但是在多线程的运行中,指令重排序可能会影响程序的执行结果的,我们通过一张图来直观地观察一下:
JVM学习(八)指令重排序的更多相关文章
- 初识指令重排序,Java 中的锁
本文是作者原创,版权归作者所有.若要转载,请注明出处.本文只贴我觉得比较重要的源码 指令重排序 Java语言规范JVM线程内部维持顺序化语义,即只要程序的最终结果与它顺序化情况的结果相等,那么指令的执 ...
- JVM学习--(二)内存模型、可见性、指令重排序
我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存模型 首先我们思考一下一个java线程要向另外一个线程进行通信,应该怎么做,我们再 ...
- java并发学习--第九章 指令重排序
一.happns-before happns-before是学习指令重排序前的一个必须了解的知识点,他的作用主要是就是用来判断代码的执行顺序. 1.定义 happens-before是用来指定两个操作 ...
- JVM并发机制的探讨——内存模型、内存可见性和指令重排序
并发本来就是个有意思的问题,尤其是现在又流行这么一句话:“高帅富加机器,穷矮搓搞优化”. 从这句话可以看到,无论是高帅富还是穷矮搓都需要深入理解并发编程,高帅富加多了机器,需要协调多台机器或者多个CP ...
- 轻松学JVM(二)——内存模型、可见性、指令重排序
上一篇我们介绍了JVM的基本运行流程以及内存结构,对JVM有了初步的认识,这篇文章我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存 ...
- 深入理解JVM(二)——内存模型、可见性、指令重排序
上一篇我们介绍了JVM的基本运行流程以及内存结构,对JVM有了初步的认识,这篇文章我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存 ...
- 深入理解JVM一内存模型、可见性、指令重排序
一.内存模型 首先我们思考一下一个java线程要向另外一个线程进行通信,应该怎么做,我们再把需求明确一点,一个java线程对一个变量的更新怎么通知到另外一个线程呢?我们知道java当中的实例对象.数组 ...
- Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)
一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...
- Java的多线程机制系列:(四)不得不提的volatile及指令重排序(happen-before)
一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...
随机推荐
- js 常用业务工具方法 (es5,es6)持续更新
数组去重 数组去重最原始的方法就是使用双层循环. es5: // 使用indexOf function unique(array) { var res = []; for (var i = 0, le ...
- 文华财经赢顺外盘期货行情数据API接口开放代码
文华财经赢顺外盘期货行情数据API接口开放代码 怎么才能获取到外盘期货行情数据API接口呢?不少朋友就会考虑到文华财经行情API接口,本身文华财经就是一个软件提供商,提供行情API接口也 ...
- selenium定位方法实例
selenium定位方法实例 首先打开浏览器输入微博的网址,将网页最大化,等待3秒 from selenium import webdriver import time driver = webdri ...
- 第 1 篇 Scrum 冲刺博客(5.21)
一.Alpha阶段认领的任务 二.明日任务安排 成员 5.22任务安排 工时 陈芝敏 调用小程序接口获取用户微信登录权限,初始化 1h 在页面显示倒计时 5h 冯晓凤 继续学习微信开放文档 5h 江晓 ...
- Java算法——分治法
一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简 ...
- 区块链入门到实战(33)之Solidity – 数据类型
在用任何语言编写程序时,都需要使用变量来存储各种信息.变量是内存空间的名称,变量有不同类型,例如整型.字符串类型等等.操作系统根据变量的数据类型分配内存. Solidity中,变量类型有以下几大类: ...
- foreach循環體控制
通常情況下,在程式中的cursor定義之前,整合了l_sql變量后,轉化sql語句時,通過檢查STATUS的值來判斷sql語句是否有錯誤. 語句如: if STATUS th ...
- 焦大:做SEO应该研究的用户需求的方向
http://www.wocaoseo.com/thread-60-1-1.html 最近收到打击很大,收获也颇多,这一切都莫过于用户需求的问题.我曾经给我弟说过,我对检索排名特征识别.提取和计算自认 ...
- Python 批量下载BiliBili视频 打包成软件
文章目录 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人,我给大家 ...
- Android开发之dp转像素,像素转换为dp工具类,详细代码,带有源文件下载地址。
import android.content.Context; /** * @author 官网:http://blog.csdn.net/qq_21376985 * * David编写: 微博:ht ...