happens-before

  从JDK5开始,java使用新的JSR -133内存模型(本文除非特别说明,针对的都是JSR- 133内存模型)。JSR-133提出了happens-before的概念,通过这个概念来阐述操作之间的内存可见性。如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须存在happens-before关系。这里提到的两个操作既可以是在一个线程之内,也可以是在不同线程之间。 与程序员密切相关的happens-before规则如下:

  ● 程序顺序规则:一个线程中的每个操作,happens- before 于该线程中的任意后续操作。

  ● 监视器锁规则:对一个监视器锁的解锁,happens- before 于随后对这个监视器锁的加锁。

  ● volatile变量规则:对一个volatile域的写,happens- before 于任意后续对这个volatile域的读。

  ● 传递性:如果A happens- before B,且B happens- before C,那么A happens- before C。

  注意,两个操作之间具有happens-before关系,并不意味着前一个操作必须要在后一个操作之前执行!happens-before仅仅要求前一个操作(执行的结果)对后一个操作可见,且前一个操作按顺序排在第二个操作之前(the first is visible to and ordered before the second)。happens- before的定义很微妙,后文会具体说明happens-before为什么要这么定义。

  happens-before与JMM的关系如下图所示:

  如上图所示,一个happens-before规则通常对应于多个编译器重排序规则和处理器重排序规则。对于java程序员来说,happens-before规则简单易懂,它避免程序员为了理解JMM提供的内存可见性保证而去学习复杂的重排序规则以及这些规则的具体实现。