title: Volatile guarantees and out-of-order execution
body: <p><strong>IMPORTANT EDIT</strong> I know about the "happens before" <em>in the thread where the two assignments are happening</em> my question is would it be possible for <em>another</em> thread to be reading "b" non-null while "a" is still null. So I know that if you're calling <em>doIt()</em> from the same thread as the one where you previously called <em>setBothNonNull(...)</em> then it cannot throw a NullPointerException. But what if one is calling <em>doIt()</em> <strong>from another thread</strong> than the one calling <em>setBothNonNull(...)</em> ?</p>
  
  <p>Note that this question is solely about the <code>volatile</code> keyword and the <code>volatile</code> guarantees: it is <strong>not</strong> about the <code>synchronized</code> keyword (so please don't answer "you must use synchronize" for I don't have any issue to solve: I simply want to understand the <code>volatile</code> guarantees (or lack of guarantees) regarding out-of-order execution).</p>
  
  <p>Say we have an object containing two <code>volatile</code> String references that are initialized to null by the constructor and that we have only one way to modify the two String: by calling <em>setBoth(...)</em> and that we can only set their references afterwards to non-null reference (only the constructor is allowed to set them to null).</p>
  
  <p>For example (it's just an example, there's no question yet):</p>
  
  <pre><code>public class SO {
  
      private volatile String a;
      private volatile String b;
  
      public SO() {
          a = null;
          b = null;
      }
  
      public void setBothNonNull( @NotNull final String one, @NotNull final String two ) {
          a = one;
          b = two;
      }
  
      public String getA() {
          return a;
      }
  
      public String getB() {
          return b;
      }
  
  }
  </code></pre>
  
  <p>In <em>setBothNoNull(...)</em>, the line assigning the non-null parameter "a" appears before the line assigning the non-null parameter "b".</p>
  
  <p>Then if I do this (once again, there's no question, the question is coming next):</p>
  
  <pre><code>doIt() {
      if ( so.getB() != null ) {
          System.out.println( so.getA().length );
      }
  }
  </code></pre>
  
  <p>Am I correct in my understanding that due to out-of-order execution I can get a <em>NullPointerException</em>?</p>
  
  <p>In other words: there's no guarantee that because I read a non-null "b" I'll read a non-null "a"?</p>
  
  <p>Because due to out-of-order (multi)processor and the way <code>volatile</code> works "b" could be assigned before "a"?  </p>
  
  <p><code>volatile</code> guarantees that reads subsequent to a write shall always see the last written value, but here there's an out-of-order "issue" right?  (once again, the "issue" is made on purpose to try to understand the semantics of the <code>volatile</code> keyword and the Java Memory Model, not to solve a problem).</p>