Java—指令重排序

简介: Java—指令重排序

指令重排序


指令概念

指令是指示计算机执行某种操作的命令,如:数据传送指令、算术运算指令、位运算指令、程序流程控制指令、串操作指令、处理器控制指令。指令不同于我们所写的代码,一行代码按照操作的逻辑可以分成多条指令。

举个例子:int a = 1; 这段代码大致可以分为两条指令:1.加载常量1;2.将常量1赋值给变量a。

指令重排序

只要程序的最终结果与它顺序化情况的结果相等,那么指令的执行顺序可以与代码逻辑顺序不一致,这个过程就叫做指令的重排序。

指令重排序的意义:使指令更加符合 CPU 的执行特性,最大限度的发挥机器的性能,提高程序的执行效率。

指令重排序分类

指令重排序主要分为三种,在这里主要讨论 JVM 中的指令重排序。

  1. 编译器重排序:JVM 中完成
  2. 指令级并行重排序
  3. 处理器重排序:CPU 中完成

指令重排序原则

如果程序中操作A在操作B之前,那么线程中操作A将在操作B之前执行。(只对指令内部重排序,不在指令间重排序)

  • As-If-Serial语义

不管怎么进行指令重排序,单线程内程序的执行结果不能被改变。

编译器和处理器对存在依赖关系的操作都不会对其进行重排序。只有不存在依赖关系的操作有可能进行重排序。

Happens-Before原则

保证正确同步的多线程程序的执行结果不被改变。

对于被同步的操作,如果操作 A 先于操作 B,那么 A 操作的执行结果将对 B 操作可见,而且 A 操作的执行顺序排在 B 操作之前。

管理锁定规则:一个unlock操作happen—before后面(时间上的先后顺序)对同一个锁的lock操作。 (如果线程1解锁了monitor a,接着线程2锁定了a,那么,线程1解锁a之前的写操作都对线程2可见(线程1和线程2可以是同一个线程))

防止指令重排序

volatile关键字通过“内存屏障”来防止指令被重排序。

为了实现volatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。

Java内存模型采取保守策略(见缝就插)

在每个volatile写操作的前面插入一个StoreStore屏障。 在每个volatile写操作的后面插入一个StoreLoad屏障。 在每个volatile读操作的后面插入一个LoadLoad屏障。 在每个volatile读操作的后面插入一个LoadStore屏障。

Synchronized 把多线程执行环境改变为单线程执行环境,无需关心指令重排序(单线程执行结果不会改变)。



目录
相关文章
|
2天前
|
XML 前端开发 Oracle
16:JSP简介、注释与Scriptlet、Page指令元素、Include操作、内置对象、四种属性-Java Web
16:JSP简介、注释与Scriptlet、Page指令元素、Include操作、内置对象、四种属性-Java Web
8 2
|
17天前
|
存储 缓存 安全
Java并发基础之互斥同步、非阻塞同步、指令重排与volatile
在Java中,多线程编程常常涉及到共享数据的访问,这时候就需要考虑线程安全问题。Java提供了多种机制来实现线程安全,其中包括互斥同步(Mutex Synchronization)、非阻塞同步(Non-blocking Synchronization)、以及volatile关键字等。 互斥同步(Mutex Synchronization) 互斥同步是一种基本的同步手段,它要求在任何时刻,只有一个线程可以执行某个方法或某个代码块,其他线程必须等待。Java中的synchronized关键字就是实现互斥同步的常用手段。当一个线程进入一个synchronized方法或代码块时,它需要先获得锁,如果
26 0
|
2月前
|
缓存 Java 计算机视觉
深入理解Java自动装箱和自动拆箱(反编译字节码理解每条指令)
在Java中,自动装箱(Autoboxing)是指将基本数据类型(如int、char等)自动转换为其对应的包装类(如Integer、Character等)的过程。而自动拆箱(Unboxing)则是将包装类的对象转换回其对应的基本数据类型的操作。这些特性从Java SE 5开始被引入,以方便开发者在处理基本类型和其包装类之间进行转换。 下面是一个简短的摘要: - **自动装箱**:当基本类型赋值给包装类时,例如 `Integer i = 1;`,Java会自动调用Integer的`valueOf()`方法,将int转换为Integer对象。对于数值在-128到127之间的int,会使用Int
42 2
深入理解Java自动装箱和自动拆箱(反编译字节码理解每条指令)
|
6月前
|
存储 Java 关系型数据库
如何用JAVA调用服务器系统指令
如何用JAVA调用服务器系统指令
41 1
|
7月前
|
Java 编译器 测试技术
安谋科技(Arm China)刘庆川:借助Arm SIMD指令提升Java应用性能
2023年9月22日,系列课程收官的最后一节《借助Arm SIMD指令提升Java应用性能》正式上线,由安谋科技(Arm China)高级工程师刘庆川主讲,内容涵盖:SIMD 指令及 Java VM介绍、如何在 Java 应用中使用 SIMD 指令、Java Vector API在 倚天上的案例分析。本期节目在阿里云官网、阿里云微信视频号、阿里云钉钉视频号、InfoQ 官网、阿里云开发者微信视频号、阿里云创新中心直播平台 & 微信视频号同步播出,同时可以点击【https://developer.aliyun.com/topic/ecs-yitian】进入【倚天实例迁移课程官网】了解更多内容。
安谋科技(Arm China)刘庆川:借助Arm SIMD指令提升Java应用性能
|
8月前
|
JavaScript 前端开发 Java
Javaweb第四章---Vue与指令(入门必看)
Javaweb第四章---Vue与指令(入门必看)
38 0
|
11月前
|
Java 索引
Java的i = i++与i=++i的去呗从JVM指令讲解图文并茂,一文必懂
Java的i = i++与i=++i的去呗从JVM指令讲解图文并茂,一文必懂
210 0
|
12月前
|
关系型数据库 Java MySQL
【Linux】Linux中的常用指令和将java程序运行环境部署到Linux
【Linux】Linux中的常用指令和将java程序运行环境部署到Linux
|
存储 Java 编译器
01-Dos基本指令和编译运行Java文件
Java 是Sun公司于1995年5月推出的语言,与我同岁
93 0
|
Java 编译器
【JVM原理探索】class字节码指令方法[调用]详解(上) | Java开发实战
【JVM原理探索】class字节码指令方法[调用]详解(上) | Java开发实战
126 0
【JVM原理探索】class字节码指令方法[调用]详解(上) | Java开发实战