title: Explain how JIT reordering works
body: <p>I have been reading a lot about synchronization in Java and all the problems that can occur. However, what I'm still slightly confused about is how the JIT can reorder a write.</p>
  
  <p>For instance, a simple double check lock makes sense to me:</p>
  
  <pre><code>  class Foo {
      private volatile Helper helper = null; // 1
      public Helper getHelper() { // 2
          if (helper == null) { // 3
              synchronized(this) { // 4
                  if (helper == null) // 5
                      helper = new Helper(); // 6
              }
          }
          return helper;
      }
  }
  </code></pre>
  
  <p>We use volatile on line 1 to enforce a happens-before relationship. Without it, is entirely possible for the JIT to reoder our code. For example:</p>
  
  <ol>
  <li><p>Thread 1 is at line 6 and memory is allocated to <code>helper</code> however, the constructor has not yet run because the JIT could reordering our code.</p></li>
  <li><p>Thread 2 comes in at line 2 and gets an object that is not fully created yet. </p></li>
  </ol>
  
  <p>I understand this, but I don't fully understand the limitations that the JIT has on reordering.</p>
  
  <p>For instance, say I have a method that creates and puts a <code>MyObject</code> into a <code>HashMap&lt;String, MyObject&gt;</code> (I know that a <code>HashMap</code>is not thread safe and should not be used in a multi-thread environment, but bear with me). Thread 1 calls createNewObject:</p>
  
  <pre><code>public class MyObject {
      private Double value = null;
  
      public MyObject(Double value) {
          this.value = value;
      }
  }
  
  Map&lt;String, MyObject&gt; map = new HashMap&lt;String, MyObject&gt;();
  
  public void createNewObject(String key, Double val){
      map.put(key, new MyObject( val ));
  }
  </code></pre>
  
  <p>At the same time thread 2 calls a get from the Map. </p>
  
  <pre><code>public MyObject getObject(String key){
      return map.get(key);
  }
  </code></pre>
  
  <p>Is it possible for thread 2 to receive an object from <code>getObject(String key)</code> that is not fully constructed? Something like:</p>
  
  <ol>
  <li>Thread 1: Allocate memory for <code>new MyObject( val )</code></li>
  <li>Thread 1: Place object in map</li>
  <li>Thread 2: call <code>getObject(String key)</code> </li>
  <li>Thread 1: Finish constructing the new MyObject.</li>
  </ol>
  
  <p>Or will <code>map.put(key, new MyObject( val ))</code> not put an object into the map until it's fully constructed?</p>
  
  <p>I'd imagine that the answer is, it wouldn't put an object into the Map until it is fully constructed (because that sounds awful). So how can the JIT reorder? </p>
  
  <p>In a nutshell can it only reorder when creating a new <code>Object</code> and assigning it to a reference variable, like the double checked lock? A complete rundown on the JIT might be much for a SO answer, but what I'm really curious about is how it can reorder a write (like line 6 on the double checked lock) and what stops it from putting an object into a <code>Map</code> that is not fully constructed.</p>