# Happens-Before
在JMM中,如果
一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须存在happens-before关系。其描述的是可见性问题操作之间存在Happens-Before关系, 并不意味着按照
Happens-Before规则的顺序来执行, 在重排序之后, 执行结果与Happens-Before规则执行结果一致即可.
# 介绍几种HB规则
这里只列举出与Programmer相关的规则
# 程序执行的顺序性规则
在一个线程中, 前面的操作Happens-Before后面的操作
# volatile变量规则
对一个volatile变量的写操作一定Happens-Before其后面对这个变量的读操作
# 传递性规则
若A Happens-Before B, 且B Happens-Before C, 则A Happens-Before C.
# 锁的规则
对一个锁的解锁操作Happens-Before后面对这个锁的加锁
# 线程启动规则
主线程在启动子线程前的所有操作Happens-Before于子线程的任意操作
# 线程中断规则
对线程interrupt()方法的调用Happens-Before于被中断线程的代码检测到中断事件的发生
# 线程等待规则
它是指主线程 A 等待子线程 B 完成(主线程 A 通过调用子线程 B 的 join() 方法实现),当子线程 B 完成后(主线程 A 中 join() 方法返回),主线程能够看到子线程的操作。当然所谓的“看到”,指的是对共享变量的操作。
# 对象终结规则
一个对象的初始化完成Happens-Before于他的finalize()方法的开始
# 场景&案例
# 案例1
下面的案例代码reader()方法中, 通过if(v)判断后, 能否读到x=42?
此时应用了Happens-Before规则中的
程序执行的顺序性规则、volatile变量规则、传递性规则说明一下此处传递性规则的体现. 由于
x=42Happens-Beforev=true, 且v=trueHappens-Before读v, 因此根据传递性规则所述, 则x=42Happens-Before读x.
public class TT {
int x = 0;
volatile boolean v = false;
public void writer() {
x = 42;
v = true;
}
public void reader() {
if (v) {
System.out.println(x);
}
}
}