Java 的 Happens-Before 原则 定义了一些规则,用于确保线程之间的数据一致性和代码执行顺序
Happens-Before 的 8 条原则如下:
1. 程序次序规则(Program Order Rule)
描述:在一个线程中,代码的执行顺序按照程序中书写的顺序执行。(考虑if-else这种的话,实际上指的是控制流顺序)
解释:在一个线程内,代码会按照程序的书写顺序依次执行,因此前一个操作总是先于后一个操作完成。例如,在 Thread A 中,语句 int a = 1; happens-before a = 2;。
2. 锁定规则(Monitor Lock Rule)
描述:一个 unlock 操作 先行发生于后面对同一锁的 lock 操作。
解释:如果线程 A 先释放一个锁,线程 B 之后获得这个锁,那么线程 A 在释放锁前对共享变量的所有修改对线程 B 可见。这一规则确保了锁释放之前的操作能够在锁的下次获取时被其他线程看到。
3. volatile 变量规则(Volatile Variable Rule)
描述:对 volatile 变量的写操作先行发生于后续对这个变量的读操作。
解释:如果线程 A 写入一个 volatile 变量,线程 B 随后读取这个变量,那么线程 A 的写操作对线程 B 是可见的。这意味着对 volatile 变量的写操作会刷新到主内存,而读操作会从主内存中读取。
4. 线程启动规则(Thread Start Rule)
描述:Thread对象的start()方法先行发生于此线程的每一个动作。。
解释:如果线程 A 启动线程 B(即调用 B.start()),那么线程 A 在启动线程 B 之前的操作对线程 B 可见。此规则确保线程 B 能看到其启动前主线程的所有操作。
5. 线程终止规则(Thread Termination Rule)
描述:线程中的所有操作都先行发生于对该线程的终止检测操作(例如 Thread.join())。
解释:如果线程 A 调用 Thread B 的 join() 方法并成功返回,那么线程 B 中的所有操作都 happens-before 线程 A 中的 join() 操作。这一规则保证了线程 A 在调用 join() 返回后,可以看到线程 B 所做的所有操作。
6. 线程中断规则(Thread Interruption Rule)
描述:对线程的中断操作 interrupt() 先行发生于被中断线程检测到中断事件。可以通过Thread.interrupted()方法检测到是否有中断发生。
解释:如果线程 A 调用了线程 B 的 interrupt() 方法,那么线程 B 中检测到中断信号时,A 的 interrupt() 操作对 B 是可见的。即,线程 A 调用 interrupt() 后,线程 B 在中断后要读取的任何数据对线程 B 都是可见的。
7. 对象终结规则(Finalizer Rule)
描述:一个对象的初始化完成(构造函数执行完成)先行发生于它的finalize()方法开始。
解释:对象的构造完成后,其 finalize() 方法才可能被调用。这一规则保证了构造函数中的操作对 finalize() 方法是可见的,因此对象的资源在 finalize() 中可以安全地进行回收。
8. 传递性规则(Transitivity Rule)
描述:如果操作A先行发生于操作B,操作B先行发生于操作C,可以得出操作A先行发生于操作C。
解释:Happens-before 是一种传递性的关系。这意味着如果 A 先于 B,且 B 先于 C,那么可以推断 A 先于 C。这种传递性帮助我们建立更复杂的 happens-before 关系链。
总结
Happens-Before 原则在并发编程中为程序员提供了内存可见性和操作顺序的基本保障。利用这些规则,可以确保线程之间的数据一致性和代码执行顺序,避免数据竞争和内存不可见性问题。
285

被折叠的 条评论
为什么被折叠?



