title: Visibility effects of synchronization in Java
body: <p><a href="https://wiki.sei.cmu.edu/confluence/display/java/LCK10-J.+Use+a+correct+form+of+the+double-checked+locking+idiom" rel="nofollow noreferrer">This</a> article says:</p>
  
  <blockquote>
    <p>In this noncompliant code example, the Helper class is made immutable
    by declaring its fields final. The JMM guarantees that immutable
    objects are fully constructed before they become visible to any other
    thread. The block synchronization in the getHelper() method guarantees
    that all threads that can see a non-null value of the helper field
    will also see the fully initialized Helper object.</p>
  </blockquote>
  
  <pre><code>public final class Helper {
    private final int n;
  
    public Helper(int n) {
      this.n = n;
    }
  
    // Other fields and methods, all fields are final
  }
  
  final class Foo {
    private Helper helper = null;
  
    public Helper getHelper() {
      if (helper == null) {            // First read of helper
        synchronized (this) {
          if (helper == null) {        // Second read of helper
            helper = new Helper(42);
          }
        }
      }
  
      return helper;                   // Third read of helper
    }
  }
  </code></pre>
  
  <blockquote>
    <p>However, this code is not guaranteed to succeed on all Java Virtual
    Machine platforms because there is no happens-before relationship
    between the first read and third read of helper. Consequently, it is
    possible for the third read of helper to obtain a stale null value
    (perhaps because its value was cached or reordered by the compiler),
    causing the getHelper() method to return a null pointer.</p>
  </blockquote>
  
  <p>I don't know what to make of it. I can agree that there is no happens before relationship between first and third read, at least no <strong>immediate</strong> relationship. Isn't there a transitive happens-before relationship in a sense that first read must happen before second, and that second read has to happen before third, therefore first read has to happen before third</p>
  
  <p>Could someone elaborate more proficiently? </p>