文章目录

  • 一、指令重排序规范
  • 二、happens-before 先行发生原则

一、指令重排序规范


指令重排指的是 , 线程中如果两行代码 没有逻辑上的上下关系 , 可以对代码进行 重新排序 ;

JVM 指令重排遵循规范 :

① as-if-serial 规范 : 单个线程中, 指令的重排 , 不能影响程序的执行结果 ;

  • 可以重排的情况 : 对于下面代码 , 两条指令顺序颠倒 , 执行结果相同 , 可以进行指令重排 ;
x = 0;
y = 1;
  • 不可以进行重排的情况 : 对于下面的代码 , 两条指令如果上下颠倒 , 结果不同 , 不可以进行指令重排 ;
x = 0;
y = x;

② happens-before 规范 : 先行发生原则 ;

二、happens-before 先行发生原则


happens-before 先行发生原则 : A happens-before B , A 先于 B 发生 , 先 A 后 B ;

Java 虚拟机在编译时和运行时 , 会对 JVM 指令进行重排优化 , 很明显 , 指令重排会对线程并发产生影响 ;

为了保证并发编程的安全性 , 这里 规定了一些场景下 , 禁止在这些场景中 使用 指令重排 ;

happens-before 先行发生原则 适用场景 : 在以下场景中 , 不进行指令重排 , 这些先后顺序 , 绝对不能被打乱 , 否则会出现严重线程安全问题 ;

  • 程序次序原则 : 在程序内 , 按照代码书写的执行顺序 , 前面的代码先执行 , 后面的代码后执行 ; 时间上 靠前 的操作 先于 时间上靠后 的操作 执行 ;
  • 管程锁规则 : 不论是单线程还是多线程 , 线程 A 解锁后 , 线程 B 获取该锁 , 可以看到线程 A 的操作结果 ; 解锁的操作 先于 加锁的操作 ; 线程 B 要加锁 , 必须等待线程 A 解锁完毕才可以 ;
  • volatile 规则 : volatile 关键字修饰的变量 , 线程 A 对该变量的写操作 先于 线程 B 读取该变量的操作 , 线程 A 对该变量的写操作的结果对于线程 B 一定可见 ;
  • 线程启动规则 : 线程 start() 方法 先于 线程的具体执行的操作 ; 线程必须先启动 , 然后才能执行线程内的代码逻辑 ;
  • 线程终止规则 : 线程的具体操作 先于 线程的终止检测 ; 线程的代码逻辑执行完成 , 然后进行线程的终止检测 ;
  • 传递性 : happens-before 规则具有传递性 ; 如果 A happens-before B 和 B happens-before C , 则 A happens-before C ;
  • 线程中断 : 调用线程 interrupt() 方法 , 先于 被中断线程的代码 检测到 中断时 事件的发生 ; 必须先发生中断 , 然后才能被检测到 ; 不能还没发生中断 , 就可以检测到中断发生 ;
  • 对象终结 : 对象的创建 先于 对象的终结 , 创建就是调用构造函数 , 终结就是调用 finalize 方法 ;

只要符合上述规则 , 不需要进行同步 , 就可以成立 ;

通过 " happens-before 先行发生原则 " 可以判定两个线程的操作 , 是否有发生冲突的可能 ;

【Java 并发编程】指令重排序规范 ( happens-before 先行发生原则 )相关推荐

  1. java面试-Java并发编程(二)——重排序

    当我们写一个单线程程序时,总以为计算机会一行行地运行代码,然而事实并非如此. 什么是重排序? 重排序指的是编译器.处理器在不改变程序执行结果的前提下,重新排列指令的执行顺序,以达到最佳的运行效率. 重 ...

  2. 【Java 并发编程】线程指令重排序问题 ( 指令重排序规范 | volatile 关键字禁止指令重排序 )

    文章目录 总结 一.指令重排序规范 二.指令重排序示例 总结 Java 并发的 333 特性 : 原子性 : 每个操作都是 不可拆分的原子操作 ; 在线程中进行 a++ 就不是原子操作 , 该操作分为 ...

  3. 由Java引起的指令重排序思考

    背景 问题出现 最近遇到了一个NullPointerException,虽然量不大,但是很怪异,大致长这个样子 这是个什么空指针?居然说我LinkedList.iterator().hasNext() ...

  4. JAVA中JVM的重排序详细介绍(写得很明白)

    刚刚在研究volatile变量的时候,涉及到重排序的概念,于是发现了这篇很好的文章,写得很简短很明白.所以转载一下. 原文地址:JAVA中JVM的重排序详细介绍 原文贴出来: 重排序通常是编译器或运行 ...

  5. 什么是指令重排序和内存屏障,看完你就懂了

    面试官在问到多线程编程的时候,指令重排序.内存屏障经常会被提起.如果你对这两者有一定的理解,那这就是你的加分项. (一)什么是指令重排序 为了使处理器内部的运算单元能尽量被充分利用,处理器可能会对输入 ...

  6. Java并发编程之指令重排序

    在我们面试过程中,通常避免不了会被问到什么是指令重排序?本文就这个问题进行探索. 重排序 前言 一.重排序种类 二.happens-before 三.重排序 1.数据依赖性 2. as-if-seri ...

  7. java volidate线程安全_03.(多线程与并发)面试题-02--Volidate的原理和指令重排序

    线程栈(线程的工作内存)保存了线程运行时候变量值信息.当线程访问某一个对象时候值的时候,首先通过对象的引用找到对应在堆内存的变量的值,然后把堆内存变量的具体值load到线程本地内存中,建立一个变量副本 ...

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

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

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

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

最新文章

  1. ubuntu18.04.4 中 下载 github 代码 并创建 python 虚拟环境virtualenv
  2. 网络推广专员教大家网站SEO优化中锚文本的使用技巧
  3. C++11 多线程库使用说明
  4. 回顾微软近年来对于Linux和开源的策略
  5. 安卓学习笔记28:文件流操作
  6. html设置导入字体样式表,HTML CSS@face 导入字体
  7. @tap和@click的区别_计算属性---uview工作笔记001
  8. QQ超市模拟排配2D版1.14 (XNA4.0) (增加截图功能、新建地图功能)
  9. 还在搭建传统IT架构的你,正在慢慢被行业淘汰
  10. P2P流量的监控与管理方案
  11. 七个问题透视百度智慧商业平台
  12. aruco字典如DICT_4X4_50含义
  13. 拿到20W年薪offer的面试总结
  14. 圣诞树的雪花飘飘(结尾附源码)
  15. 零样本分割系列论文(2)Open-Vocabulary Instance Segmentation via Robust Cross-Modal Pseudo-Labeling
  16. 再战Trojan.PSW.Lmir.kuo、Trojan.PSW.Misc.kcc等网游盗号木马(第2版)
  17. 云队友丨如何“优雅”地进行职场沟通?
  18. 计算机超频的方法,原来电脑超频如此简单,小白也能轻松搞定
  19. 解决使用堡垒机(天玥网络安全审计系统)总是提示控件加载超时的情况
  20. win10安装oracle 12c报错[INS-30131] 附解决方法

热门文章

  1. 【图文】Excel中vlookup函数的使用方法
  2. DzzOffice增加应用对扩展名文件的支持设置,将会在Beta中提供。
  3. SQL SERVER2000教程-第四章 创建和维护表 第二节 数据完整性
  4. 由熊猫烧香引发的思考
  5. Linux入侵类问题排查思路
  6. win10 安装microsoft.net framework3.5
  7. Chrome插件(Extensions)开发实践
  8. struts2 获取 session
  9. 杭电多校(三)2019.7.29--暑假集训
  10. 查询每日规定时间段内的记录