title: Guava cachebuilder - put when load in progress
body: <p>Consider this simple program:</p>
  
  <pre><code>import java.util.concurrent.ExecutionException;
  import java.util.logging.Logger;
  
  import com.google.common.cache.CacheBuilder;
  import com.google.common.cache.CacheLoader;
  import com.google.common.cache.LoadingCache;
  
  public class Main {
  
      final static Logger logger = Logger.getLogger(Main.class.getName());
  
      public static void main(String[] args) throws ExecutionException, InterruptedException {
  
          final LoadingCache&lt;Integer, String&gt; cache = CacheBuilder.newBuilder().build(
                  new CacheLoader&lt;Integer, String&gt;() {
  
                      @Override
                      public String load(Integer arg0) throws Exception {
                          logger.info("Cache builder START: " + arg0);
                          Thread.sleep(4000);
                          logger.info("Cache builder FINISH: " + arg0);
                          return "This is what CacheBuilder returned for key " + arg0;
                      }
                  });
  
          Thread getterThread = new Getter(cache);
          getterThread.start();
  
          Thread setterThread = new Setter(cache);
          setterThread.start();
  
          getterThread.join();
          setterThread.join();
  
          logger.info("Finally in cache we have: " + cache.get(1));
  
      }
  
      private static final class Getter extends Thread {
          private final LoadingCache&lt;Integer, String&gt; cache;
  
          private Getter(LoadingCache&lt;Integer, String&gt; cache) {
              this.cache = cache;
          }
  
          @Override
          public void run() {
              try {
                  logger.info("Getter thread reads 1st time " + cache.get(1)
                          + "  &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; WHAT !?!");
                  // allow the setter to put the value
                  try {
                      Thread.sleep(500);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  logger.info("Getter thread reads 2nd time " + cache.get(1));
              } catch (ExecutionException e) {
                  e.printStackTrace();
              }
          }
      }
  
      private static final class Setter extends Thread {
          private final LoadingCache&lt;Integer, String&gt; cache;
  
          private Setter(LoadingCache&lt;Integer, String&gt; cache) {
              this.cache = cache;
          }
  
          @Override
          public void run() {
              try {
                  // deliberately wait to allow the Getter thread
                  // trigger cache loading
                  try {
                      Thread.sleep(200);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  cache.put(1, "This isn't where I parked my car!");
                  logger.info("Setter thread now reads: " + cache.get(1));
              } catch (ExecutionException e) {
                  e.printStackTrace();
              }
          }
      }
  }
  </code></pre>
  
  <p>And the output is:</p>
  
  <pre><code>2013-11-08 15:24:32 INFO Main$1 load Cache builder START: 1
  2013-11-08 15:24:32 INFO Main$Setter run Setter thread now reads: This isn't where I parked my car!
  2013-11-08 15:24:36 INFO Main$1 load Cache builder FINISH: 1
  2013-11-08 15:24:36 INFO Main$Getter run Getter thread reads 1st time This is what CacheBuilder returned for key 1  &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; WHAT !?!
  2013-11-08 15:24:37 INFO Main$Getter run Getter thread reads 2nd time This isn't where I parked my car!
  2013-11-08 15:24:37 INFO Main main Finally in cache we have: This isn't where I parked my car!
  </code></pre>
  
  <p>I'm getting this "This is what CacheBuilder returned for key 1" in Getter thread. 
  Obviously this is because the get(1) called by Getter triggers cache loading, but meanwhile the Setter thread comes and puts some other value for key 1.
  I'd expect it to return the same what was just put before by Setter = "This isn't where I parked my car!" (which I get the 2nd time Getter retrieves value for 1).</p>
  
  <p>Did I miss something ?</p>
  
  <p>Thanks in advance</p>