Happens-before

2020-08-22  本文已影响0人  香菜那么好吃为什么不吃香菜

原则

  1. 如果操作A happens—before B,那么A操作的执行结果对操作B可见,并且操作A的执行顺序排在操作B之前。
  2. 如果两个操作之间存在happens-before关系,并不意味着一定要按照happens-before原则制定的顺序来执行。如果重新排序之后的执行结果与按照happens-before关系执行的结果一致,那么这种重排序并不非法。

happens-before判断

· 程序次序规则:在一个单独的线程中,按照程序代码的执行流顺序,(时间上)先执行的操作happens-before(时间上)后执行的操作。同一线程中前面的所有写操作对后面的操作课件
· 管理锁定规则:一个unlock操作happens-before后面(时间上先后顺序)对同一个锁的lock操作。如果线程 1 解锁了a,接着线程2锁定了a,那么线程1解锁a之前的写操作都对线程2可见(线程1和线程2可以为同一个线程)
· volatile变量规则:对一个volatile变量的写操作happens-before后面(时间上)对该变量的读操作。
如果线程1 写入了volatile变量v(临界变量),接着线程2 读取了v,那么线程1 写入v以及之前的写操作都对线程2可见,线程1 和线程2可以是同一个线程**
· 线程启动规则:Thread.start()方法happens-before调用start的线程前的每一个操作。假定线程A 在执行过程中,通过执行Thread B.start()来启动线程B,那么线程A在线程B开始执行前对共享变量的修改在接下来的线程B可见。注意:线程B启动后,线程A再对共享变量的修改,线程B未必可见
· 线程终止规则:线程的所有操作都happens-before对此线程的终止检测,可以通过threadjoin()方法结束,thread.isAlive()的返回值等手段检测到线程已经终止执行。线程t1写入的所有变量,在任意其他线程t2调用t1.join()或者t1.isAlive()成功返回后,都对t2可见
· 线程中断规则:对线程interrupt()的调用happens-before发生于被中断线程的代码检测到中断时事件的发生。线程t1写入的所有变量,调用thread.interrupt(),被打断的线程t2,可以看到t1的全部操作
· 对象终结规则:一个对象的初始化完成(构造函数执行结束)happen-before它的finalize()方法的开始。当对象调用finalize()方法时,对象初始化完成的任意操作,同步到全部主存,同步到全部cache
· 传递性:如果操作A happens-before操作B,操作B happens-before操作C,那么操作A happens-before 操作C。

在程序运行的过程中个,所有的变更会先在寄存器或者本地cache中完成,然后才会被拷贝到主存以跨越内存栅栏,此种跨越序列或者顺序成为happens-before。
注:happens-before本质是顺序,重点是跨越内存栅栏
通常情况下,写操作必须要happens-before读操作,即写线程需要在所有度线程跨越内存栅栏之前完成自己的跨越动作,其所作的变更才会对其他线程可见。

上一篇下一篇

猜你喜欢

热点阅读