关于重排序

重排序通常是编译器或运行时环境为了优化程序性能而采取的对指令进行重新排序执行的一种手段。

重排序分为两类:编译期重排序和运行期重排序,分别对应编译时和运行时环境。

As-if-serial语义

as-if-serial语义的意思是,所有的动作(Action)都可以为了优化而被重排序,但是必须保证它们重排序后的结果和程序代码本身的应有结果是一致的。

Java编译器、运行时和处理器都会保证单线程下的as-if-serial语义。

比如,为了保证这一语义,重排序不会发生在有数据依赖的操作之中。

int a = 1;
int b = 2;
int c = a + b;

将上面的代码编译成Java字节码或生成机器指令,可视为展开成了以下几步动作(实际可能会省略或添加某些步骤)。

对a赋值1
对b赋值2
取a的值
取b的值
将取到两个值相加后存入c

在上面5个动作中,动作1可能会和动作2、4重排序,动作2可能会和动作1、3重排序,动作3可能会和动作2、4重排序,动作4可能会和1、3重排序。但动作1和动作3、5不能重排序。动作2和动作4、5不能重排序。因为它们之间存在数据依赖关系,一旦重排,as-if-serial语义便无法保证。

内存屏障

内存屏障(Memory Barrier,或叫做内存栅栏,Memory Fence)是一组处理器指令,用于实现对内存操作的顺序限制,控制特定条件下的重排序和内存可见性问题。Java编译器会根据内存屏障的规则禁止重排序。

内存屏障可以被分为以下几种类型
LoadLoad屏障:对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。
StoreStore屏障:对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。
LoadStore屏障:对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。
StoreLoad屏障:对于这样的语句Store1; StoreLoad; Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。它的开销是四种屏障中最大的。在大多数处理器的实现中,这个屏障是个万能屏障,兼具其它三种内存屏障的功能。

有的处理器的重排序规则较严,无需内存屏障也能很好的工作,Java编译器会在这种情况下不放置内存屏障。
为了实现上一章中讨论的JSR-133的规定,Java编译器会这样使用内存屏障。

内容来自美团网技术博客

好文书签

Java内存访问重排序的研究

深入理解Java内存模型(二)——重排序

内存屏障与JVM并发

理解重排序

Java内存访问重排序笔记的更多相关文章

  1. java内存模型——重排序

    线程安全问题概括来说表现为三个方面:原子性,可见性和有序性. 在多核处理器的环境下:编译器可能改变两个操作的先后顺序:处理器可能不是完全依照程序的目标代码所指定的顺序执行命令:一个处理器执行的多个操作 ...

  2. java内存模型-重排序

    数据依赖性 如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖性.数据依赖分下列三种类型: 名称 代码示例 说明 写后读 a = 1;b = a; 写一个变量之 ...

  3. java高并发核心要点|系列4|CPU内存指令重排序(Memory Reordering)

    今天,我们来学习另一个重要的概念. CPU内存指令重排序(Memory Reordering) 什么叫重排序? 重排序的背景 我们知道现代CPU的主频越来越高,与cache的交互次数也越来越多.当CP ...

  4. 《深入理解 Java 内存模型》读书笔记

    ![img](https://mmbiz.qpic.cn/mmbiz_jpg/1flHOHZw6RtPu3BNx3zps1JhSmPICRw7QgeOmxOfTbCT3RLgIo4qRpn6xL4qg ...

  5. 转《深入理解 Java 内存模型》读书笔记

    转:https://mp.weixin.qq.com/s/2hA6u4hLEPWlTPdD-XB-bg 前提 <深入理解 Java 内存模型>程晓明著,该书在以前看过一遍,现在学的东西越多 ...

  6. java基础之 重排序

    重排序通常是编译器或运行时环境为了优化程序性能而采取的对指令进行重新排序执行的一种手段.重排序分为两类:编译期重排序和运行期重排序,分别对应编译时和运行时环境. 在并发程序中,程序员会特别关注不同进程 ...

  7. java内存知识点扩展_笔记

    一.java的虚拟机分为三大区域: 执行引擎, java运行内存, 类加载器 1.1.Java运行内存分为线程共享区域和线程私有区: 我们大多数初学者用的都是sun公司最早设计的Java HotSpo ...

  8. Java并发编程原理与实战四十一:重排序 和 happens-before

    一.概念理解 首先我们先来了解一下什么是重排序:重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段. 从Java源代码到最终实际执行的指令序列,会分别经历下面3种重排序,如下图 ...

  9. 13 Java内存模型

    数据竞争 int a=0, b=0; public void method1() { int r2 = a; b = 1; } public void method2() { int r1 = b; ...

随机推荐

  1. servlet的一个web容器中有且只有一个servlet实例或有多个实例的理解1

    servlet的一个web容器中有且只有一个servlet实例或有多个实例的理解 (2013-06-19 19:30:40) 转载▼     servlet的非线程安全,action的线程安全 对提交 ...

  2. int(11)最大长度是多少,MySQL中varchar最大长度是多少(转)

    int(11)最大长度是多少,MySQL中varchar最大长度是多少? int(11)最大长度是多少? 在SQL语句中int代表你要创建字段的类型,int代表整型,11代表字段的长度. 这个11代表 ...

  3. WPF 注册全局快捷键

    .NET技术交流群 199281001 .欢迎加入. using System; using System.Collections.Generic; using System.Linq; using ...

  4. 【原创】express3.4.8源码解析之中间件

    前言 注意:旧文章转成markdown格式. 中间件(middleware)的概念来自于TJ的connect库,express就是建立在connect之上. 就如同connect的意思是 连接 一样, ...

  5. javascript仿天猫加入购物车动画效果

    javascript仿天猫加入购物车动画效果   注意:首先需要声明的是:代码原思路不是我写的,是在网上找的这种效果,自己使用代码封装了下而已:代码中都有注释,我们最主要的是理解抛物线的思路及在工作中 ...

  6. Excel加密的Sheet如何hack

    Excel的加密sheet如何hack: 思路:在VBA中添加穷举法模块函数并运行 源代码: Sub PasswordBreaker() 'Breaks worksheet password prot ...

  7. thinkphp中I方法

    概述 正如你所见到的一样,I方法是ThinkPHP众多单字母函数中的新成员,其命名来自于英文Input(输入),主要用于更加方便和安全的获取系统输入变量,可以用于任何地方,用法格式如下:I('变量类型 ...

  8. 微信5.4你所不知道的事 X5浏览引擎提速50%-80%

    微信5.4新增包括搜索公众号.识别图中二维码.面对面收钱等功能,但是你可知道新版微信X5浏览引擎提速了,提升50%-80%的网络传输速度及相同比例流量节省? 从X5浏览引擎开发人员得知,X5浏览技术基 ...

  9. 忘记mysql root用户密码

    今天帮一个售后的同事解决网盘无登录的问题,看了下后台日志,报错用密码root连接不上数据库,然后我就强行改了一下数据库密码,就OK了. (1)用root登录系统. (2)vim /etc/my.cnf ...

  10. php面试题之五——PHP综合应用(高级部分)

    五.PHP综合应用 1.写出下列服务的用途和默认端口(新浪网技术部) ftp.ssh.http.telnet.https ftp:File Transfer Protocol,文件传输协议,是应用层的 ...