title: ConcurrentHashMap reorder instruction?
body: <p>I'm looking into ConcurrentHashMap implementation and have a thing make me confused.</p>
  
  <pre><code>/* Specialized implementations of map methods */
  
          V get(Object key, int hash) {
              if (count != 0) { // read-volatile
                  HashEntry&lt;K,V&gt; e = getFirst(hash);
                  while (e != null) {
                      if (e.hash == hash &amp;&amp; key.equals(e.key)) {
                          V v = e.value;
                          if (v != null)
                              return v;
                          return readValueUnderLock(e); // recheck
                      }
                      e = e.next;
                  }
              }
              return null;
          }
  </code></pre>
  
  <p>and</p>
  
  <pre><code>    /**
       * Reads value field of an entry under lock. Called if value
       * field ever appears to be null. This is possible only if a
       * compiler happens to reorder a HashEntry initialization with
       * its table assignment, which is legal under memory model
       * but is not known to ever occur.
       */
      V readValueUnderLock(HashEntry&lt;K,V&gt; e) {
          lock();
          try {
              return e.value;
          } finally {
              unlock();
          }
      }
  </code></pre>
  
  <p>and HashEntry constructor   </p>
  
  <pre><code>/**
       * ConcurrentHashMap list entry. Note that this is never exported
       * out as a user-visible Map.Entry.
       *
       * Because the value field is volatile, not final, it is legal wrt
       * the Java Memory Model for an unsynchronized reader to see null
       * instead of initial value when read via a data race.  Although a
       * reordering leading to this is not likely to ever actually
       * occur, the Segment.readValueUnderLock method is used as a
       * backup in case a null (pre-initialized) value is ever seen in
       * an unsynchronized access method.
       */
      static final class HashEntry&lt;K,V&gt; {
      final K key;
              final int hash;
              volatile V value;
              final HashEntry&lt;K,V&gt; next;
  
              HashEntry(K key, int hash, HashEntry&lt;K,V&gt; next, V value) {
                  this.key = key;
                  this.hash = hash;
                  this.next = next;
                  this.value = value;
              }
  </code></pre>
  
  <p>put implement</p>
  
  <pre><code>tab[index] = new HashEntry&lt;K,V&gt;(key, hash, first, value);
  </code></pre>
  
  <p>I confused at HashEntry comment, as <a href="http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html">JSR-133</a>, once HashEntry is constructed, all final fields will be visible to all other threads, <strong>value</strong> field is volatile, so I think it visible to other threads too??? . Other point, is the reorder he said is: HashEntry object reference can be assigned to tab[...] before it is full constructed (so result is other threads can see this entry but e.value can be null) ?</p>
  
  <p><strong>Update:</strong>
  I read <a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html">this</a> article and it's good. But do I need to care about a case like this</p>
  
  <pre><code>ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();
  
  thread1:
  
  Person p=new Person("name","student");        
  queue.offer(new Person());
  
  thread2:
  Person p = queue.poll();
  </code></pre>
  
  <p>Is there a chance that thread2 receive an unfinished-construct Person object just like HashEntry in </p>
  
  <blockquote>
    <p>tab[index] = new HashEntry(key, hash, first, value);
    ?</p>
  </blockquote>