引言

Java的内存模型是主内存和工作内存,我们在进行程序调用的时候,变量值都是从主内存中读取然后复制一个副本,对这个副本进行操作。到最后将这个副本再更新到主内存中。但是这个只是针对于单线程,那如果是多线程呢?并且操作的是同一个变量值,那这两个线程之间的可见性应该如何来定义呢?

happens-Before

简介

  • java使用JMM模型后那就使用happens-before来阐述两个线程间的可见性
  • 在JMM中,如果一 个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系。这里提到的两个操作既可以是在一个线程之内,也可以是在不同线程之间。

规则

  • 程序顺序规则:一个线程中的每个操作,在前面的操作都happen-before他之后的操作。这也就是我们在一个方法中下面的变量总是可以拿到上面变量的值。
  • 监视器锁规则:对于一个锁的解锁,happens-before于对这个锁的加锁。监视器锁那就想想sychronized 当我们锁定某个对象的时候,解锁后那对于下一次来的线程会先知道这个锁是无锁状态,随后就加上锁。再理解一下就是监视器的加锁和解锁是线程间可见的。
  • volatile变量规则:对于volatile的写,对于后续的读都是happens-before的。volite的两个作用,防止指令重排和变量间线程可见。其中被修饰变量间线程可见,也就是我们在这里所说的线程间可见。
  • 有时候有人就会想volatile为什么能保证共享变量能线程间可见呢?其中有一种回答是,这个共享变量加了volatile关键字后后来的线程会先将工作内存中的数据先更新进主内存然后再去拿。仔细想想这是不是很牵强。要是有很多线程都共享这个变量了,那这难道把这些工作内存的变量都拉进到主内存更新,那主内存应该以哪个为准呢?解释不通呀。那我们使用这个happens-before变量规则来解释。就说他遵循happens-before规则。那这还是能说的过去的。那就又有人纠结了,那happens-before那又是咋回事呢?这他妈的是规范???

happens-before到底是什么?

  • 上面废话了那么多,我觉得我自己晕了。
  • 在强调一遍:java使用JMM模型后那就使用happen-before来阐述两个线程间的可见性
  • 那怎样就能是happens-before了?怎么就遵循happens-before,怎么就两个线程间可见了?
  • 线程间的可见,两种方式内存共享和消息传递。那我们如果说使用sychronized的锁对某个方法加锁,多个线程调用这个方法,那就可以说这几个线程间是happens-before的。
  • 还有就是一个成员变量被volatile 关键字修饰了,那有多个线程来修改这个变量,那这几个线程间也是有happens-before关系的。
  • 看一下下面的这张图来自(java并发编程艺术)我个人的理解是,遵循jMM定义的规则,且能保证线程间安全,这多个线程间就能使用happens-before对他们关系进行描述。

总结

  • 第三遍 java使用JMM模型后那就使用happens-before来阐述两个线程间的可见性
  • 写完感觉这东西也没什么。

参考

《java并发编程的艺术》

理解java中的happens-Before相关推荐

  1. 深入理解Java中的内存泄漏

    理解Java中的内存泄漏,我们首先要清楚Java中的内存区域分配问题和内存回收的问题本文将分为三大部分介绍这些内容. Java中的内存分配 Java中的内存区域主要分为线程共享的和线程私有的两大区域: ...

  2. 理解Java中的弱引用(Weak Reference)

    理解Java中的弱引用(Weak Reference) 本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限, ...

  3. 深入理解Java中的final关键字

    深入理解Java中的final关键字 http://www.importnew.com/7553.html Java中的final关键字非常重要,它可以应用于类.方法以及变量.这篇文章中我将带你看看什 ...

  4. 如何理解 JAVA 中的 volatile 关键字

    如何理解 JAVA 中的 volatile 关键字 最近在重新梳理多线程,同步相关的知识点.关于 volatile 关键字阅读了好多博客文章,发现质量高适合小白的不多,最终找到一篇英文的非常通俗易懂. ...

  5. java中demo接人_return的用法_如何理解java中return的用法?

    C语言中return用法?(请熟练者进) return是返回值,这个返回值是和函数的类型有关的,函数的类型是什么,他的返回值就是什么 比方主函数intmain() {}这里就必须有一个return,只 ...

  6. java弱引用怎么手动释放,十分钟理解Java中的弱引用,十分钟java引用

    十分钟理解Java中的弱引用,十分钟java引用 本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,帮助大家理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限 ...

  7. 深入理解Java中的逃逸分析

    转载自  深入理解Java中的逃逸分析 在Java的编译体系中,一个Java的源代码文件变成计算机可执行的机器指令的过程中,需要经过两段编译,第一段是把.java文件转换成.class文件.第二段编译 ...

  8. 一文带你理解Java中Lock的实现原理

    转载自   一文带你理解Java中Lock的实现原理 当多个线程需要访问某个公共资源的时候,我们知道需要通过加锁来保证资源的访问不会出问题.java提供了两种方式来加锁,一种是关键字:synchron ...

  9. java 类 null_深入理解java中的null“类型”

    本文研究的主要是java中的null"类型"的相关实例,具体介绍如下. 先给出一道简单的null相关的题目,引发我们对null的探讨,后面会根据官方语言手册对null"类 ...

  10. 如何理解Java中的自动拆箱和自动装箱?

    小伟刚毕业时面的第一家公司就被面试官给问住了,记忆尤深啊- 如何理解Java中的自动拆箱和自动装箱? 自动拆箱?自动装箱?什么鬼,听都没听过啊,这-这-知识盲区- 回到家后小伟赶紧查资料,我透,这不就 ...

最新文章

  1. 北大AI公开课2019 | 商汤科技沈徽:AI创新与落地
  2. 关于OUTLOOK 2007邮件无法打印的问题解决方法
  3. 多少线程太多? [关闭]
  4. 如何让SD-WAN超越MPLS?
  5. 谷歌云服务宕机,苹果iCloud也不行了
  6. Linux下jetty报java.lang.OutOfMemoryError: PermGen space及Jetty内存配置调优解决方案
  7. Element-UI-的布局和容器---Element-UI工作笔记003
  8. tensorflow 在加载大型的embedding模型参数时,会遇到cannot be larger than 2GB
  9. go语言多态接口样例
  10. 普林斯顿微积分读本05第四章--求解多项式的极限问题
  11. jspstudy 升级mysql_jspstudy+myeclipse 搭建jsp开发环境
  12. android 外卖源码,外卖人8.7源码外卖人订餐系统仿美团饿了么外卖安卓APP
  13. 《ERP原理》期末复习——第四章 基础数据
  14. 小程序倒计时显示晃动问题
  15. .NETReflector的破解
  16. 小码哥教育笔记之VueDay01课程回顾
  17. asp实训报告摘要_ASP实训总结
  18. 【文科生带你读JavaScript数据结构与算法】2. 双向链表与LRU缓存算法原理与实现(下)
  19. 研究生学术道德考试 部分题目 Word可搜索版
  20. python直角坐标转极坐标_Python在OpenCV里实现极坐标变换功能

热门文章

  1. Apple 在中国的维修和保修政策
  2. 图像超分综述:超长文一网打尽图像超分的前世今生 (附核心代码)
  3. 【超分辨率】从SRCNN到EDSR,总结深度学习端到端超分辨率方法发展历程
  4. React生命周期解析
  5. word list 1
  6. 虚拟机RedHatEenterpriseLinux5安装及Oracle10.2.0安装手记收藏
  7. 大型企业使用树莓派进行弱网测试通用流程
  8. 成型泡沫组件的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  9. Linux_命令行基础及挂载和目录文件管理
  10. 图片轮换的按钮如何通过像素定位