理解java中的happens-Before

引言

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并发编程的艺术》

猜你喜欢

转载自blog.csdn.net/weixin_40413961/article/details/108741594