lotus

贵有恒何必三更眠五更起 最无益只怕一日曝十日寒

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  1. happens-before 规则含义:
    happens-before原则是JMM最核心的概念,理解happens-before是理解JMM的关键
    JMM为了使编译器和处理器的约束尽可能少,它遵循的原则是:只要不改变程序的执行结果,编译器和处理器想怎么优化就怎么优化。

    happens-before原则简单理解前一个操作的结果对后续操作可见。

    JMM向程序员保证:一个操作happens-before于另一个操作,那么第一个操作的执行结果将对第二个执行结果可见,而且第一个操作的执行顺序排在第二个顺序之前。

    happens-before原则的目的:为了在不改变程序执行结果的前提下,尽可能提高程序执行的并行度。

  2. happens-before 规则定义
    2.1 程序顺序规则
    一个线程中,按程序顺序,前面的操作happens-before于后续任何操作。
    例如

    int i = 1;// A
    int j = 2;// B
    int x = i*j;// C
    

    A操作happens-before与B、C操作。

    2.2 监控器锁规则
    对一个锁的解锁,happens-before与随后对这个锁的加锁。
    这个规则说的锁指的是java里的synchronized,例如下面代码,在正式进入同步代码块之前,会自动加锁,而在代码块执行结束后会自动释放锁,加锁和释放锁是编译器帮助我么实现的。

    synchronized(this){ // 自动加锁
        if(this.name.equals("a")){
          this.name = "b";
      }
    }// 自动解锁
    

    假设name的初始值是a,线程A执行完代码块后,name的值变成了b(执行完自动释放锁),线程B进入代码块可以看见线程A对name的操作,也就是线程B能看见name==“b”。

  3. volatile变量规则
    对一个volatile域的写,happens-before与任意后续对这个volatile域的读

  4. 传递性
    如果A happens-before B, 且B happens-before C 那么A happens-before C

    class Demo {
      int x = 0;
      volatile boolean f = false;
      public void writer(){
        x = 10;
        f = true;
      }
      public void reader(){
          if( f == true ){
              System.out.println(x);
          }
       }
    }
    

根据规则1:x = 10 happens-before 写变量 f = true ,
根据规则3:写变量 f = true happens-before 读变量 f = true
根据规则4 传递性:x = 10 happens 读变量 f = true 因此会输出 10。

  1. start()规则
    主线程A启动子线程B后,子线程B能看见主线程在启动子线程B的操作

  2. join()规则
    如果线程A执行ThreadB.join()并成功返回,那么线程B的任意操作happens-before 于 线程A从ThreadB.join()操作成功返回

总结:Happens-before的语义本质上是一种可见性A happens-before B 意味着A事件对B事件来说是可见的,无论A事件和B事件是否发生在同一线程中。

JMM的设计分为两部分,一部分是happens-before原则,他是面向程序员提供的,阐述了一个强内存模型,我们只需要理解happens-before原则,就可以编写并发安全的程序了。 另一部分是针对JVM实现的,为了尽可能少的对编译器和处理器做约束,从而提高性能。JMM在不影响程序执行结果的前提下对其不做要求,即允许优化重排序。



posted on 2022-09-23 17:14  白露~  阅读(225)  评论(0编辑  收藏  举报