happen-before可真是一个经典又老生常谈的话题,规则一共就八条,但看起来总有种抓不住 重点的感觉。今天再整理一下对这八条规则的理解。
首先我的理解是happen-before的语义与在什么什么之前发生完全没有关系,其语义是如果 Ahapen-bforeB,那么A的结果对B是可见的。通过这些规则可以保证程序按我们预想的方式 运转。
总的来说,HB原则是对单线程环境下的指令重排序以及多线程环境下的线程间数据的一致性 进行的约束。单线程情况下保证串行语义,多线程情况下因为数据的一致性需要我们自己声明 和保证,所以JVM自行保证了 HB原则中提出的它认为必须要保证一致性的情况。
1、 单线程happen-before原则:在同一个线程中,书写在前面的操作happen-before后面的 操作。
首先是单线程的HB,前面的操作产生的结果必须对后面的操作可见。而不是前面的操作必须 先于后面的操作执行,比如按照as-if-serial语义,没有数据依赖的两条指令是可以进行重 排序的。而这种情况对于HB原则来说,因为两条指令都没有产生对方需要的结果,而不需要 对对方可见,及时执行顺序被调转也是符合HB原则的。
2、 锁的happen-before原则:同一个锁的unlock操作happen-before此锁的lock操作。
个人理解强调的是解锁操作在多线程环境的可见性。一个线程进行了解锁操作,对于晚于该操 作的加锁操作必须能够及时感应到锁的状态变化。解锁操作的结果对后面的加锁操作一定是可见的,无论两个是否在一个线程。
3、 volatile 的 happen-before 原则:对一个 volatile 变量的写操作 happen-before 对此变 量的任意操作。
对volatile变量的写操作的结果对于发生于其后的任何操作的结果都是可见的。x86架构下 volatile通过内存屏障和缓存一致性协议实现了变量在多核心之间的一致性。
4、 happen-before 的传递性原则:如果 A 操作 happen-beforeB 操作,B 操作 happen-beforeC 操作,那么A操作happen-beforeC操作。
HB可以说是两项操作之间的偏序关系,满足偏序关系的各项性质,我们都知道偏序关系中有 一条很重要的性质:传递性,所以Happens-Before也满足传递性。这个性质非常重要,通过 这个性质可以推导岀两个没有直接联系的操作之间存在Happens-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方法调用。
单线程下对象的创建于销毁存在数据依赖,该条原则强调的是多线程情况下对象初始化的结果 必须对发生于其后的对象销毁方法可见。

Was this helpful?

0 / 0

发表回复 0

Your email address will not be published.