简述happens-before八大原则
在Java内存模型中,happens-before的意思是前一个操作的结果可以被后续操作获取。
https://zhuanlan.zhihu.com/p/434045508
程序次序规则:
在一个线程中,按照代码的顺序,前面的操作先行发生于后面的任意操作。在同一个线程中,程序在前面对某个变量的修改一定是对后续操作可见的。
volatile变量规则:
对 volatile 变量的写操作先行发生于后面的读操作
传递性规则:
如果操作 A 先行发生于操作 B,操作 B 先行发生于操作 C,那么操作 A 先行发生于操作 C
锁定规则:
对一个锁的解锁操作先行发生于后续对这个锁的加锁操作。
例如,下面的代码,在进入synchronized代码块之前,会自动加锁,在代码块执行完毕后,会自动释放锁。
我们可以这样理解这段程序:假设变量x的值为10,线程A执行完synchronized代码块之后将x变量的值修改为10,并释放synchronized锁。
当线程B进入synchronized代码块时,能够获取到线程A对x变量的写操作,也就是说,线程B访问到的x变量的值为10。
线程的 start 方法先行发生于线程的每个动作
上述代码是在线程A中执行的一个代码片段,根据线程的启动规则,线程A启动线程B之后,线程B能够看到线程A在启动线程B之前的操作,在线程B中访问到的x变量的值为100。
对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生。
例如,下面的程序代码。在线程A中中断线程B之前,将共享变量x的值修改为100,则当线程B检测到中断事件时,访问到的x变量的值为100。
线程中所有操作先行发生于对线程的终止检测。
线程A等待线程B完成(在线程A中调用线程B的join()方法实现),当线程B完成后(线程A调用线程B的join()方法返回),则线程A能够访问到线程B对共享变量的操作。
例如,在线程A中进行的如下操作。
一个对象的初始化完成Happens-Before于它的finalize()方法的开始。
import java.util.*; public class Main { public Main() { System.out.println("gou zao"); } @Override protected void finalize() throws Throwable { System.out.println("xiao hui"); } public static void main(String[] args) { new Main(); System.gc(); } }
gou zao
xiao hui
简述CountDownLatch
countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。 是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,调用countDown方法,计数器的值就减1,
当计数器的值为0时,表示所有线程都执行完毕,然后在等待的线程就可以恢复工作了。 只能一次性使用,不能reset。