前言

在程序执行时,为了提高性能,编译器和处理器会对指令进行重排序。

为了明确定义多线程场景下重排序的问题(可见性、有序性、原子性),Java引入了JMM(Java Memory Model),也就是Java内存模型。JMM为JAVA程序员提供了8条规则,即happen-before原则。根据happen-before原则,就可以在不理解复杂的重排序规则情况下,解决因重排序而导致的多线程间可见性、有序性等问题。

happen-before原则

两个操作具有happen-before关系,并不意味着前一个操作比后一个操作先执行!happen-before仅要求前一个操作的执行结果对后一个操作可见

可以将happen-before原则分两部分理解,单线程与多线程环境下的happen-before。单线程下通过语义分析数据依赖关系,编译器和处理器可以合理的优化我们的代码。但是多线程情况下不同线程间的数据依赖关系有我们定义,处理器与编译器都无法通过分析感知

happen-before原则定义了某些特定场景下多线程间的数据依赖关系。即happen-before原则是对单线程环境下的指令重排序以及多线程环境下的线程间数据的一致性进行的约束

对八条原则的理解来自:牛有肉:happen-before原则的理解

(1) 单线程happen-before原则:在同一个线程中,书写在前面的操作happen-before后面的操作。

首先是单线程的 happen-before ,前面的操作产生的结果必须对后面的操作可见。而不是前面的操作必须先于后面的操作执行,比如按照 as-if-serial 语义,没有数据依赖的两条指令是可以进行重排序的。而这种情况对于 happen-before 原则来说,因为两条指令都没有产生对方需要的结果,而不需要对对方可见,及时执行顺序被调转也是符合 happen-before 原则的。

(2) 锁的happen-before原则:同一个锁的unlock操作happen-before此锁的lock操作。

个人理解强调的是解锁操作在多线程环境的可见性。一个线程进行了解锁操作,对于晚于该操作的加锁操作必须能够及时感应到锁的状态变化。解锁操作的结果对后面的加锁操作一定是可见的,无论两个是否在一个线程。

(3) volatile的happen-before原则: 对一个volatile变量的写操作happen-before对此变量的任意操作。

对 volatile 变量的写操作的结果对于发生于其后的任何操作的结果都是可见的。x86 架构下volatile 通过内存屏障和缓存一致性协议实现了变量在多核心之间的一致性。

(4) happen-before的传递性原则: 如果A操作 happen-before B操作,B操作happen-before C操作,那么A操作happen-before C操作。

happen-before 可以说是两项操作之间的偏序关系,满足偏序关系的各项性质,我们都知道偏序关系中有一条很重要的性质:传递性,所以happen-before也满足传递性。这个性质非常重要,通过这个性质可以推导出两个没有直接联系的操作之间存在happen-before关系

(5) 线程启动的happen-before原则:同一个线程的start方法happen-before此线程的其它方法。

start 放法与其它方法可能并没有数据依赖关系,但是显而易见的,为了程序的正确性,我们必须做到这一点。start 方法造成的函数副作用必须对其它方法可见。

(6) 线程中断的happen-before原则:对线程interrupt方法的调用happen-before被中断线程的检测到中断发送的代码。

interrupt 方法改变的状态必须对后续执行的检测方法可见。

(7) 线程终结的happen-before原则:线程中的所有操作都happen-before线程的终止检测。

为了安全的关闭线程,线程中的方法造成的函数副作用必须对线程关闭方法可见。

(8)对象创建的happen-before原则:一个对象的初始化完成先于他的finalize方法调用。

单线程下对象的创建于销毁存在数据依赖,该条原则强调的是多线程情况下对象初始化的结果必须对发生于其后的对象销毁方法可见。

happen-before原则的理解相关推荐

  1. [vue] 说说你对vue组件的设计原则的理解

    [vue] 说说你对vue组件的设计原则的理解 第一: 容错处理, 这个要做好, 极端场景要考虑到, 不能我传错了一个参数你就原地爆炸 第二: 缺省值(默认值)要有, 一般把应用较多的设为缺省值 第三 ...

  2. [Vue][面试]谈一谈对vue的设计原则的理解

    谈一谈对vue的设计原则的理解 思路: 在vue官网上写着大大的定义和特点: -渐进式JavaScript框架 -易用.灵活和高效 渐进式JavaScript框架: 与其它大型框架不同的是,Vue被设 ...

  3. 对“端到端”原则的理解

    对"端到端"原则的理解 前些天读了两篇论文,一篇是J.H.Saltzer,D.P.Read 和D.D.Clark 在80年代初发表的<The End-TO-End Argum ...

  4. 设计模式六大原则的理解与归纳

    文章目录 一.开闭原则 二.里氏代换原则 三.依赖倒转原则 四.接口隔离原则 五.迪米特法则 六.合成复用原则 一.开闭原则 对扩展开放,对修改关闭.在程序需要进行拓展的时候,不能去修改原有的代码,实 ...

  5. 对访问控制中最小特权原则的理解

    在网上看到许多资料介绍访问控制中的一个基本原则"最小特权原则"是"在需要时才给用户分配所需的权限",感觉这样如果从字面理解的会产生歧义,如果不在授权时为操作者指 ...

  6. MySQL 最左原则的理解

    先看下规则:一下是美团的技术 建索引的几大原则 1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>.<.between.like)就停止匹配,比如a = 1 ...

  7. 我对软件设计原则的理解

    1. 开闭原则 软件实体(class,模块,功能或业务,微服务etc)对修改关闭,对拓展开放. 抽象构建框架,实现拓展细节. 面向抽象编程,而不是面向具体实现编程.因为抽象相对来说是稳定的,让类去依赖 ...

  8. 接口隔离原则-快速理解

    定义 用多个专门的接口,而使用单一的总接口,客户端不应该依赖它不需要的接口 一个类对一个类的依赖应该建立在最小的接口上 建立单一接口,不要建立庞大臃肿的接口 尽量细化接口,接口中的方法尽量少 注意 适 ...

  9. 关于AWS中最小权限原则的理解

    目录 1. 关于最小权限原则 2. 案例分析 1. 关于最小权限原则 最小权限是指每个程序和系统用户都应该具有完成任务所必需的最小权限集合. 对于系统管理员而言,一个用户应该只能访问履行他的相关职责所 ...

最新文章

  1. Spring AOP + Redis解决重复提交的问题
  2. 说说你对 SVG 理解?
  3. Python 字符串前面加u,r,b的含义
  4. CSS中overflow:scroll怎么设置只上下滚动而不左右滚动
  5. asp.net web 开发登录相关操作的控件LoginName、LoginStatus和LoginView控件使用详解
  6. 强力推荐!飞桨产业级PaddleNLP最新全景图发布
  7. 花里胡哨,不协调统一的界面,正如看到一个穿花里胡哨衣服的人,让人作呕,不想接近。...
  8. 小米12能效有望显著提升:骁龙8 Gen1功不可没
  9. 洛谷P2507 [SCOI2008]配对
  10. vs 执行单个文件,如cpp
  11. arcgis js平滑线工具_Arcgis中文字体、平滑线插件使用说明
  12. Vscode搭建jdk源码阅读环境 wsl
  13. OPNsense用户手册-高可用性和硬件故障转移
  14. 在Sbo Add-on插件中实现通用的模态数据选择
  15. 二叉树、满二叉树、完全二叉树、平衡二叉树、二叉排序树、线索二叉树
  16. 市场份额正在“迅速衰退”!华为将如何纾困?
  17. prometheus 配置服务器监控、服务监控、容器中服务监控与告警
  18. RFM模型与Spark实现
  19. 了解美杜莎(Medusa)
  20. 中文zh描述规则,原来中文下除了cmn外还有14种扩展

热门文章

  1. P2408 不同子串个数
  2. J - Just Multiplicative Inverse Gym - 102875J
  3. SP10707 COT2 - Count on a tree II
  4. 牛客题霸 [矩阵的最小路径和] C++题解/答案
  5. 牛客题霸 反转链表 C++题解/答案
  6. L2-005 集合相似度 (25分)
  7. HDU 6889 Graph Theory Class(CCPC网络赛)
  8. [国家集训队]middle(二分+主席树[中位数思维题])
  9. 模板:拉格朗日插值(多项式)
  10. 模板:2-SAT问题