一、数据依赖性

  在学习JVM的指令重排序之前,我们先了解一下什么是数据依赖性:

  编译器和处理器在处理具体的指令时,可能会对操作进行重排序来提高执行性能【多条指令并行执行,所以提升性能的同时也可能会导致指令乱序;而上面3种情况,只要重排序两个操作的执行顺序,程序的执行结果就会被改变。

  编译器和处理器在重排序时,会遵守数据依赖性,编译器和处理器不会改变存在数据依赖关系的两个操作的执行顺序。

  PS:这里所说的数据依赖性仅针对单个处理器中执行的指令序列和单个线程中执行的操作,不同处理器之间和不同线程之间的数据依赖性不被编译器和处理器考虑。

二、相关规则

as if serial语义

  义:不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不会改变。

  解析:编译器、runtime和处理器都必须遵守as-if-serial语义。 为了遵守as-if-serial语义,编译器和处理器不会对存在数据依赖关系的操作做重排序,因为这种重排序会改变执行结果。 但是,如果操作之间不存在数据依赖关系,这些操作就可能被编译器和处理器重排序。

happen-before原则

  定义:一个线程中的每一个操作happens-before于该线程的任意后续操作,这里的happens-before并不是前一个操作必须早于后一个操作, 而是前一个操作必须对后一个操作可见,否则不能重排序。

程序次序规则

  定义:一段程序代码的执行在单个线程中看起来是有序的,不过因为虚拟机可能会对程序代码进行指令重排序,虽然进行重排序,但是最终执行的结果是与程序顺序执行的结果一致的。

三、重排序对多线程的影响

  我们前面知道了,在单线程运行中,指令重排序不能影响程序执行的结果,但是在多线程的运行中,指令重排序可能会影响程序的执行结果的,我们通过一张图来直观地观察一下:

JVM学习(八)指令重排序的更多相关文章

  1. 初识指令重排序,Java 中的锁

    本文是作者原创,版权归作者所有.若要转载,请注明出处.本文只贴我觉得比较重要的源码 指令重排序 Java语言规范JVM线程内部维持顺序化语义,即只要程序的最终结果与它顺序化情况的结果相等,那么指令的执 ...

  2. JVM学习--(二)内存模型、可见性、指令重排序

    我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存模型 首先我们思考一下一个java线程要向另外一个线程进行通信,应该怎么做,我们再 ...

  3. java并发学习--第九章 指令重排序

    一.happns-before happns-before是学习指令重排序前的一个必须了解的知识点,他的作用主要是就是用来判断代码的执行顺序. 1.定义 happens-before是用来指定两个操作 ...

  4. JVM并发机制的探讨——内存模型、内存可见性和指令重排序

    并发本来就是个有意思的问题,尤其是现在又流行这么一句话:“高帅富加机器,穷矮搓搞优化”. 从这句话可以看到,无论是高帅富还是穷矮搓都需要深入理解并发编程,高帅富加多了机器,需要协调多台机器或者多个CP ...

  5. 轻松学JVM(二)——内存模型、可见性、指令重排序

    上一篇我们介绍了JVM的基本运行流程以及内存结构,对JVM有了初步的认识,这篇文章我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存 ...

  6. 深入理解JVM(二)——内存模型、可见性、指令重排序

    上一篇我们介绍了JVM的基本运行流程以及内存结构,对JVM有了初步的认识,这篇文章我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存 ...

  7. 深入理解JVM一内存模型、可见性、指令重排序

    一.内存模型 首先我们思考一下一个java线程要向另外一个线程进行通信,应该怎么做,我们再把需求明确一点,一个java线程对一个变量的更新怎么通知到另外一个线程呢?我们知道java当中的实例对象.数组 ...

  8. Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

  9. Java的多线程机制系列:(四)不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

随机推荐

  1. 安全可靠国产系统背景下的应用开发应有.NET Core的一席之地

    在中美当前背景下的安全可靠国产系统(简称安可),安可产业要实现技术自主可控,需要在四个层面逐步实现:基础硬件设施,如芯片.服务器.存储.交换机.路由器:底层软件,包括操作系统.数据库.中间件等:应用软 ...

  2. 更改默认Xcode

    更改默认 Xcode 的指令: sudo xcode-select -switch /Applications/Xcode.app  如果系统里面有好几个版本的 Xcode,可以用这个命令指定默认的 ...

  3. Tensorflow2(一)深度学习基础和tf.keras

    代码和其他资料在 github 一.tf.keras概述 首先利用tf.keras实现一个简单的线性回归,如 \(f(x) = ax + b\),其中 \(x\) 代表学历,\(f(x)\) 代表收入 ...

  4. Spring Security使用数据库数据完成认证--练气后期2

    写在前面 没错,这篇文章还是练气后期!但作者我相信筑基指日可待! 在前一篇文章当中,我们简单地分析了一下Spring Security的认证流程,知道了如果想要实现对自己用户数据(账户.角色.权限)的 ...

  5. mybatis逆向工程介绍

    项目的model一旦多了起来,复杂了起来,我们很自然的想到使用mybatis的逆向工程来生成相应的pojo和mapper,能节省很多精力. MyBatis Generator(MBG)是 MyBati ...

  6. 《神经网络的梯度推导与代码验证》之FNN(DNN)前向和反向过程的代码验证

    在<神经网络的梯度推导与代码验证>之FNN(DNN)的前向传播和反向梯度推导中,我们学习了FNN(DNN)的前向传播和反向梯度求导,但知识仍停留在纸面.本篇章将基于深度学习框架tensor ...

  7. android,在java代码中,如何给textview设置不同的颜色,以及引用color中资源设置颜色

    textV.setTextColor(Color.parseColor("#FF0000")); <pre name="code" class=" ...

  8. Mybatis入门篇之基础CRUD

    前言 作为一个资深后端码农天天都要和数据库打交道,最早使用的是 Hiberate,一个封装性极强的持久性框架.自从接触到 Mybatis 就被它的灵活性所折服了,可以自己写 SQL,虽然轻量级,但是麻 ...

  9. C#垃圾代码随机生成器

    直接上代码: using UnityEngine; using System.Collections.Generic; using UnityEditor; using System.IO; usin ...

  10. org.xml.sax.SAXParseException: The processing instruction target matching "[xX][mM][lL]" is not allowed(转)

    xml文件不能被正确解析/The processing instruction target matching "[xX][mM][lL]" is not allowed. The ...