06-happens-before

1.什么是happens-before

  在设计Java内存模型时(JMM),需要考虑两个因素,一个是内存模型做到可见性保证并易于理解、易于编程,另一个是编译器与处理器希望内存模型的约束对它们越少越好,这样它们就可以尽可能多的优化来提高性能,但是这两个因素又很冲突,所以要寻找一个平衡点,一方面要为程序员提供内存可见性保证,另一个方面对编译器与处理的限制要尽可能的放松,通过happens-before来达到平衡点的设计,可以说happens-before是JMM的核心概念。

2.happens-before提供给JMM的禁止重排分类

  1. 会改变程序执行执行结果的重排序
  2. 不会改变程序执行结果的重排序

对于会改变程序执行执行结果的重排序,JMM会要求编译器与处理器必须下禁止这种重排

对于不会改变程序执行结果的重排序,JMM对编译器与处理器不做要求(JMM允许重排)

3.happens-before的定义

  1. 如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作在第二个操作之前执行
  2. 两个操作之间存在happens-before关系,并不意味着Java平台的具体实现必须按照happens-before关系指定的顺序来执行,如果重排序后的结果与happens-before顺序执行的结果一致,那么这种重排合法,JMM允许这种重排

4.happens-before规则

  1. 程序顺序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作
  2. 监视器规则:对一个锁的解锁,happens-before于随后对这个锁的加锁
  3. volatile变量规则:对一个volatile域的写,happens-before于任意后续对volatile域的读
  4. 传递性:如果A happens-before B,B happens-before C,那么A happens-before C
  5. start()规则:如果线程A执行操作ThreadB.start(),那么A线程的ThreadB.start()操作happens-before于线程B中的任意操作。
  6. join()规则:如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作happens-before于线程A从ThreadB.join()操作成功返回。

5.happens-before与as-if-serial

happens-before与as-if-serial都是一个意思,只不过维度不同,as-if-serial是保证单线程的执行结果不改变,happens-before是保证正确同步的多线程的执行结果不改变。

  1. as-if-serial给编写单线程的程序员造成了一个假象,单线程程序是按照程序的顺序来执行的
  2. happens-before给编写正确同步多线程的程序员造成了一个假象,正确同步的多线程程序是按happens-before指定的顺序来执行的

参考:

《Java并发编程的艺术》

你可能感兴趣的:(java多线程)