title: Is ConcurrentHashMap.get() guaranteed to see a previous ConcurrentHashMap.put() by different thread?
body: <p>Is <a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html#get%28java.lang.Object%29" rel="noreferrer"><code>ConcurrentHashMap.get()</code></a> <em>guaranteed</em> to see a previous <a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html#put%28K,%20V%29" rel="noreferrer"><code>ConcurrentHashMap.put()</code></a> by different thread?  My expectation is that is is, and reading the JavaDocs seems to indicate so, but I am 99% convinced that reality is different.  On my production server the below <em>seems</em> to be happening.  (I've caught it with logging.)</p>
  
  <p>Pseudo code example:</p>
  
  <pre><code>static final ConcurrentHashMap map = new ConcurrentHashMap();
  //sharedLock is key specific.  One map, many keys.  There is a 1:1 
  //      relationship between key and Foo instance.
  void doSomething(Semaphore sharedLock) {
      boolean haveLock = sharedLock.tryAcquire(3000, MILLISECONDS);
  
      if (haveLock) {
          log("Have lock: " + threadId);
          Foo foo = map.get("key");
          log("foo=" + foo);
  
          if (foo == null) {
              log("New foo time! " + threadId);
              foo = new Foo(); //foo is expensive to instance
              map.put("key", foo);
  
          } else
              log("Found foo:" + threadId);
  
          log("foo=" + foo);
          sharedLock.release();
  
      } else
          log("No lock acquired");
  } 
  </code></pre>
  
  <p>What seems to be happening is this:</p>
  
  <pre><code>Thread 1                          Thread 2
   - request lock                    - request lock
   - have lock                       - blocked waiting for lock
   - get from map, nothing there
   - create new foo
   - place new foo in map
   - logs foo.toString()
   - release lock
   - exit method                     - have lock
                                     - get from map, NOTHING THERE!!! (Why not?)
                                     - create new foo
                                     - place new foo in map
                                     - logs foo.toString()
                                     - release lock
                                     - exit method
  </code></pre>
  
  <p>So, my output looks like this:</p>
  
  <pre><code>Have lock: 1    
  foo=null
  New foo time! 1
  foo=foo@cafebabe420
  Have lock: 2    
  foo=null
  New foo time! 2
  foo=foo@boof00boo    
  </code></pre>
  
  <p>The second thread does not immediately see the put!  Why?  On my production system, there are more threads and I've only seen one thread, the first one that immediately follows thread 1, have a problem. </p>
  
  <p>I've even tried shrinking the concurrency level on ConcurrentHashMap to 1, not that it should matter.  E.g.:</p>
  
  <pre><code>static ConcurrentHashMap map = new ConcurrentHashMap(32, 1);
  </code></pre>
  
  <p>Where am I going wrong?  My expectation?  Or is there some bug in my code (the real software, not the above) that is causing this?   I've gone over it repeatedly and am 99% sure I'm handling the locking correctly.  I cannot even fathom a bug in <code>ConcurrentHashMap</code> or the JVM.   <strong><em>Please save me from myself.</em></strong></p>
  
  <p>Gorey specifics that might be relevant:</p>
  
  <ul>
  <li>quad-core 64-bit Xeon (DL380 G5) </li>
  <li>RHEL4 (<code>Linux mysvr 2.6.9-78.0.5.ELsmp #1 SMP</code> ... <code>x86_64 GNU/Linux</code>)</li>
  <li>Java 6 (<code>build 1.6.0_07-b06</code>, <code>64-Bit Server VM (build 10.0-b23, mixed mode)</code>)</li>
  </ul>