在JMM中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须存在happens-before关系。

happens-before原则定义如下

  1. Happens-Before 是一种可见性模型,如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前。
  2. 两个操作之间存在happens-before关系,并不意味着一定要按照happens-before原则制定的顺序来执行。如果重排序之后的执行结果与按照happens-before关系来执行的结果一致,那么这种重排序并不非法。

在 JMM 中存在很多的 Happens-Before 规则:

  • 程序顺序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作;这个规则只对单线程有效,在多线程环境下无法保证正确性。
  • 监视器锁规则:一个线程对于一个锁的释放锁操作, 一定 happens-before 与后续线程对这个锁的加锁操作;
  • volatile变量规则:对一个volatile变量的写操作一定happens-before后面对这个变量的读操作;
  • 传递性规则:如果A happens-before B,且B happens-before C,那么A happens-before C。
  • 线程启动规则:如果线程 A 执行操作 ThreadB.start(),那么线程 A 的 ThreadB.start()之前的操作 happens-before 线程 B 中的任意操作;
  • join规则:线如果线程 A 执行操作 ThreadB.join()并成功返回, 那么线程 B 中的任意操作 happens-before 于线程 A 从 ThreadB.join()操作成功的返回。
  • 线程中断规则:对线程interrupted()方法的调用先行于被中断线程的代码检测到中断事件的发生。
  • 对象终结规则:一个对象的初始化完成(构造函数执行结束)先行于发生它的finalize()方法的开始。

happen-before原则是JMM中非常重要的原则,它是判断数据是否存在竞争、线程是否安全的主要依据,保证了多线程环境下的可见性。


jacheut
4 声望1 粉丝