《JAVA并发编程实战》阅读笔记1
一、 指令重排

指令重排序

Java 语言规范规定了JVM线程内部维持顺序化语义,也就是说只要程序的最终结果等同于它在严格的顺序化环境下的结果,那么指令的执行顺序就可能 与代码的顺序不一致。这个过程通过叫做指令的重排序。指令重排序存在的意义在于:JVM能够根据处理器的特性(CPU的多级缓存系统、多核处理器等)适当 的重新排序机器指令,使机器指令更符合CPU的执行特点,最大限度的发挥机器的性能。

重排序的背景

我们知道现代CPU的主频越来越高,与cache的交互次数也越来越多。当CPU的计算速度远远超过访问cache时,会产生cache wait,过多的cache  wait就会造成性能瓶颈。
针对这种情况,多数架构(包括X86)采用了一种将cache分片的解决方案,即将一块cache划分成互不关联地多个 slots (逻辑存储单元,又名 Memory Bank 或 Cache Bank),CPU可以自行选择在多个 idle bank 中进行存取。这种 SMP 的设计,显著提高了CPU的并行处理能力,也回避了cache访问瓶颈。

Memory Bank的划分
一般 Memory bank 是按cache address来划分的。比如 偶数adress 0×12345000 分到 bank 0, 奇数address 0×12345100 分到 bank1。

重排序的种类
编译期重排。编译源代码时,编译器依据对上下文的分析,对指令进行重排序,以之更适合于CPU的并行执行。

运行期重排,CPU在执行过程中,动态分析依赖部件的效能,对指令做重排序优化。

二、 happens-before规则

Java存储模型有一个happens-before原则,就是如果动作B要看到动作A的执行结果(无论A/B是否在同一个线程里面执行),那么A/B就需要满足happens-before关系。

(1)同一个线程中的每个Action都happens-before于出现在其后的任何一个Action。

(2)对一个监视器的解锁happens-before于每一个后续对同一个监视器的加锁。

(3)对volatile字段的写入操作happens-before于每一个后续的同一个字段的读操作。

(4)Thread.start()的调用会happens-before于启动线程里面的动作。

(5)Thread中的所有动作都happens-before于其他线程检查到此线程结束或者Thread.join()中返回或者Thread.isAlive()==false。

(6)一个线程A调用另一个另一个线程B的interrupt()都happens-before于线程A发现B被A中断(B抛出异常或者A检测到B的isInterrupted()或者interrupted())。

(7)一个对象构造函数的结束happens-before与该对象的finalizer的开始

(8)如果A动作happens-before于B动作,而B动作happens-before与C动作,那么A动作happens-before于C动作。

三、 理解

     开始接触happens-before规则和指令重排序的时候,着实乱了以阵子,尤其是happens-before规则的第一条,明明说了同一个线程中每个动作都happens-before其后一个动作,

而指令重排序又会对没有依赖的两个操作进行重排序,这不是相互矛盾的么?
     经过网上翻阅了一些资料以后,我的理解是,happens-before规则是用来判断一个动作对另一个动作是否可见的法则,他只是用来判断可见性的,而不是决定执行顺序的,就是说动作A和动作B 的执行顺序是可以通过指令重排发生变化的,而如果你要保证A和B的可见性关系,就必须采用其他控制手段来保证AB的执行顺序不被打乱,这样就能用happens-before规则来判断AB两个动作的可见性。 
参考信息:
http://www.infoq.com/cn/articles/java-memory-model-2?utm_source=infoq&utm_medium=related_content_link&utm_campaign=relatedContent_articles_clk
http://www.blogjava.net/xylz/archive/2010/07/03/325168.html

转载于:https://www.cnblogs.com/vipper/p/3307991.html

happens-before规则和指令重排相关推荐

  1. Java并发编程(五)JVM指令重排

    我是不是学了一门假的java...... 引言:在Java中看似顺序的代码在JVM中,可能会出现编译器或者CPU对这些操作指令进行了重新排序:在特定情况下,指令重排将会给我们的程序带来不确定的结果.. ...

  2. JVM内存模型、指令重排、内存屏障概念解析

    在高并发模型中,无是面对物理机SMP系统模型,还是面对像JVM的虚拟机多线程并发内存模型,指令重排(编译器.运行时)和内存屏障都是非常重要的概念,因此,搞清楚这些概念和原理很重要.否则,你很难搞清楚哪 ...

  3. Java内存模型与指令重排

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 转自 ...

  4. 两个例子详解并发编程的可见性问题和有序性问题,通过volatile保证可见性和有序性以及volatile的底层原理——缓存一致性协议MESI和内存屏障禁止指令重排

    1. 并发编程的可见性问题 2. 并发编程的有序性问题 3. 使用volatile关键字解决可见性问题 4. 可见性问题的本质--缓存不一致 因为cpu执行速度很快,但是内存执行速度相对于CPU很慢, ...

  5. jvm指令重排原因?怎么避免?

    原因:计算机内存操作速度远慢于CPU运行速度,所以就造成CPU空置,为了将提高CPU利用率,虚拟机会按照自己的一些规则会跳过执行慢的代码,去执行快的代码(即对代码重新排序),从而提升jvm的整体性能. ...

  6. 如何 方法内指令重排 进制_谈谈指令重排

    这个知识点也是很多人说不清道不明的地方,感觉都知道,说又说不出来.为什么会这样呢?因为这几个字,很容易被当成动词去理解,其实正确的理解是当成名词,即指令重排现象.那什么时候会产生指令重排现象呢?两个阶 ...

  7. 如何 方法内指令重排 进制_Java虚拟机jvm学习一:认识jvm的运行机制

    一.认识jvm JVM是Java Virtual Machine的简称.意为Java虚拟机 虚拟机是指通过软件模拟的具有完整硬件系统功能的.运行在一个完全隔离环境中的完整计算机系统 例如:VMWare ...

  8. Volatile:可见性保证+禁止指令重排

    Volatile 1.可见性保证 1.1 何为可见性 1.2 JAVA内存模型 1.3 voletile的实现原理 1.4.synchronized 关键字和 volatile 关键字的区别 2.禁止 ...

  9. Java中的指令重排

    在执行程序时,为了提高性能,编译器和处理器常常会对指令做重排序.重排序分3种类型: 编译器优化的重排序.编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序. 指令级并行的重排序.现代处理 ...

最新文章

  1. svn 合并分支代码到主干
  2. python expect模块_成为顶级黑客--python绝技 阅读笔记(五)
  3. 维护索引——通过重组索引提高性能
  4. MYSQL中group_concat有长度限制!默认1024
  5. 分支定义之Trunk vs Master
  6. linux httpd 内存,apache占用内存过高耗完内存?
  7. 在 Docker Machine 中使用 Mirror 服务
  8. 中国科技大学计算机学院叶辉,中国科技大学计算机科学与技术学院导师教师师资介绍简介-黄文超...
  9. Vue+element 解决浏览器自动填充记住的账号密码问题
  10. 如何在 iPhone、iPad、iPod touch 或 Mac 更新 HomePod?
  11. HTML5项目实战之旅行社网站——兼容响应式布局
  12. dnf搬砖代码Python_dnf自动搬砖脚本怎么写宝app
  13. 超全现代虚幻UE4素材网站整理
  14. arcgis 批量计算几何_ArcGIS四种计算图斑面积的方法
  15. pytorch例子学习——NEURAL TRANSFER USING PYTORCH神经迁移
  16. java实验——回文是一种“从前向后读”和“从后向前读”都相同的字符串,如“上海自来水来自海上”。设计一个程序,判断字符串是否是回文。
  17. ebay的api的开发技术笔记
  18. WebLogic:WTC在DEBUG模式下日志打印过程分析
  19. 右键菜单“发送到”的修改
  20. incident用法_incident与_accident区别

热门文章

  1. 从工具到社区,美图秀秀大规模性能优化实践
  2. 最佳实践 | 中文文案排版指北
  3. 多线程:什么是ThreadLocal?应用场景?
  4. Spring boot 入门篇
  5. Python 怎么样在函数内部对全局变量进行修改
  6. jQuery 对象及伪数组
  7. 第九届蓝桥杯java B组—第二题方格计数(详细介绍)
  8. keypair java_如何在Java中序列化和反序列化RSA KeyPair
  9. 绍中考能不能用计算机了,全国计算机二级考什么内容
  10. ML之XGBoost:XGBoost参数调优的优秀外文翻译—《XGBoost中的参数调优完整指南(带python中的代码)》(一)