Java 线程执行与变量可见性的 happen-before 关系

Java 线程执行与变量可见性的 happen-before 关系

什么是 happen-before 的关系

happen-before 的关系是保证一个线程执行的操做结果对不一样线程中的另外一个操做可见。app

Happens-before 定义程序中全部操做的部分排序。为了保证执行操做Y的线程能够看到操做X的结果(X和Y是否出如今不一样的线程中),X和Y之间必然存在一个先发生的关系。在没有happen-before 排序的状况下在两个操做之间,JVM能够根据须要自由从新排序(JIT编译器优化)。优化

happen-before 的不单单是'时间'中的动做从新排序,并且还保证了对内存的读写顺序。执行写入和读取到内存的两个线程能够在时钟时间方面与其余操做保持一致,但可能看不到彼此一致的更改(内存一致性错误),除非它们有happen-before 关系。spa

clipboard.png

如何创建 happen-before 关系?

如下是发生以前的规则:线程

  • 单线程规则:单个线程中的每一个操做都发生在该程序顺序中稍后出现的该线程中的每一个操做以前。

clipboard.png

  • 监视器锁定规则:监视器锁定(退出同步方法/块)上的解锁发生 - 在每次后续获取同一监视器锁定以前。

clipboard.png

  • 易失性变量规则:在对该相同字段的每次后续读取以前发生对易失性字段的写入。易失性字段的写入和读取具备与进入和退出监视器(读取和写入时的同步块)相似的内存一致性效果,但实际上没有获取监视器/锁定。

clipboard.png

  • 线程启动规则:线程上的 Thread.start() 调用发生在启动线程中的每一个操做以前。假设线程A经过调用threadA.start() 生成一个新线程B. 在线程B的run方法中执行的全部操做都将看到线程A调用threadA.start() 方法,以前(仅在线程A中)发生在它们以前。

clipboard.png

  • 线程链接规则:线程中的全部操做都发生在任何其余线程从该线程上的链接成功返回以前。假设线程A经过调用threadA.start() 生成一个新线程B,而后调用threadA.join() 。线程A将在 join() 调用时等待,直到线程B的run方法完成。在join方法返回后,线程A中的全部后续操做都将看到线程B的run方法中执行的全部操做都发生在它们以前。

clipboard.png

  • 传递性:若是A发生在B以前,B发生在C以前,那么A发生在C以前。
相关文章
相关标签/搜索