"Happens-before" 是 Java 并发编程中一个重要的概念,它描述了在多线程环境下操作执行的顺序和可见性。"Happens-before" 关系提供了一种规则,用于确保在一个线程中的操作对另一个线程是可见的,并定义了操作执行的相对顺序。
Happens-before 的概念:
"Happens-before" 是 Java 内存模型(Java Memory Model,JMM)中的一项原则,它建立了在并发环境中操作执行的偏序关系。在多线程程序中,线程之间的交互可能涉及到共享变量的读写、锁的释放和获取、线程的启动和终止等。Happens-before 提供了一种规则,以确定这些操作之间的顺序关系。
Happens-before 规则:
- 程序次序规则(Program Order Rule):
- 在同一个线程中,每个操作按照程序代码的顺序依次执行。
- 监视器锁规则(Monitor Lock Rule):
- 对一个锁的解锁操作
unlock
在同一个锁的后续加锁操作lock
之前发生。
// 线程1synchronized (lock) { // 操作1} // 操作2// 线程2synchronized (lock) { // 操作3} // 操作4
在上述例子中,操作1 happens-before 操作2,操作3 happens-before 操作4,因为在同一个监视器锁 lock
上的解锁操作在后续的加锁操作之前发生。
- volatile 变量规则(Volatile Variable Rule):
- 对一个
volatile
变量的写操作 happens-before 于后续对该变量的读操作。
// 线程1volatileintx=0; x=1; // 线程2inty=x;
在上述例子中,线程1中对变量 x 的写操作 happens-before 于线程2中对变量 x 的读操作。
- 线程启动规则(Thread Start Rule):
- 线程 A 启动线程 B 后,线程 B 的所有操作 happens-before 于线程 A 从
Thread.start()
方法返回。
// 线程 AThreadthreadB=newThread(() -> { // 操作5}); threadB.start(); // 操作6// 操作5 happens-before 操作6
在上述例子中,线程 B 的操作5 happens-before 于线程 A 的操作6。
- 线程终止规则(Thread Termination Rule):
- 线程 A 所有的操作 happens-before 于线程 A 被其他线程检测到已经终止。
// 线程 AThread.currentThread().join(); // 操作7
在上述例子中,操作7 happens-before 于线程 A 被其他线程检测到已经终止。
- 线程中断规则(Thread Interruption Rule):
- 线程 A 对线程 B 调用
interrupt
方法,会在线程 B 的操作中插入一个中断操作,该中断操作 happens-before 于线程 B 发现自己被中断(通过isInterrupted
方法检测到中断或抛出InterruptedException
异常)。
"Happens-before" 规则为多线程编程提供了一些基本的原则,帮助程序员理解在多线程环境中操作执行的顺序和可见性。通过合理使用锁机制和 volatile
关键字,以及遵循 "Happens-before" 规则,可以确保程序在多线程环境中的正确性和一致性。