Java内存模型中的Happens-Before规则

规则

Happens-Before 约束了编译器的优化行为,虽然允许编译器优化,但是要求编译器优化后一定遵守 Happens-Before 规则

在 Java 语言里面,Happens-Before 的语义本质上是一种可见性,A Happens-Before B意味着 A 事件对 B 事件来说是可见的,无论 A 事件和 B 事件是否发生在同一个线程里。例如 A 事件发生在线程 1 上,B 事件发生在线程 2 上,Happens-Before 规则保证线程 2上也能看到 A 事件的发生。(参考:Java并发编程实战)

  • 程序顺序规则:一个线程中,按照程序中代码顺序,前面的操作Happens-Before于后面的操作
  • volatile变量规则:对一个volatile变量的写操作Happens-Before于后续对该变量的读操作
  • 传递性规则:如果A Happens-Before B,且B Happens-Before C,则A Happens-Before C
  • 锁的规则:一个锁的解锁操作Happens-Before于该锁后续的加锁操作
  • 线程启动规则:如果线程A启动了线程B,则线程B启动前的操作Happens-Before线程B后续的操作
  • 线程结束规则:如果线程A中调用线程B的join()方法并成功返回,则线程B中的任意操作Happens-Before于该join()操作的返回
  • 中断规则:对线程interrupt()方法的调用Happens-Before于被中断线程检测到中断方法被调用
  • 终结器规则:一个对象的构造函数执行结束Happens-Before于它的finalize()方法的开始

案例

代码(来源:JSR 133 (Java Memory Model) FAQ

class VolatileExample {
    int x = 0;
    volatile boolean v = false;
    public void writer() {
        x = 42;
        v = true;
    }
    public void reader() {
        if (v == true) {
            //uses x - guaranteed to see 42.
        }
    }
}

根据程序顺序规则可知:x = 42 Happens-Before v = true
根据volatile变量规则可知:写volatile变量 v = true Happens-Before 读volatile变量 v
根据传递性规则可知:x = 42 Happens-Before 读volatile变量 v

代码

// x是共享变量, 初始值为10
int x = 10;
// synchronized中的锁是隐式实现的,会在进入代码块之前自动加锁,执行完代码块之后自动释放锁
synchronized (this) {
    if (this.x < 12) {
        this.x = 12;
    }
}

根据锁的规则可知:线程A执行完代码块之后的解锁操作Happens-Before线程B进入代码块之前的加锁操作,因此线程B进入代码块时可知x=12

代码

// x是共享变量, 初始值为10
int x = 10;

Thread threadB = new Thread(() -> {
    System.out.println("线程B可以看到x的值为:" + x);
    // 线程B将共享变量x的值改为21
    x = 21;
});
x = 12;
// 线程A中启动线程B
threadB.start();
threadB.join();
System.out.println("线程A可以看到x的值为:" + x);

根据线程启动规则可知:x = 12 Happens-Before threadB.start(),因此线程B启动后可以看到x被修改为12
根据线程结束规则可知:x = 21 Happens-Before threadB.join() ,因此主线程可以看到线程B结束前的任意操作,即将x修改为21

总结

Java并发编程中有三个核心问题:可见性、有序性和原子性,其中可见性和有序性便是由 Happens-Before 规则保证的

补充

Java并发编程中的三个核心问题是怎么产生的?

参考

JSR 133 (Java Memory Model) FAQ
Java并发编程实战

发布了37 篇原创文章 · 获赞 19 · 访问量 2431

猜你喜欢

转载自blog.csdn.net/momo57l/article/details/104390646