title: Per-key blocking Map in Java
body: <p>I'm dealing with some third-party library code that involves creating expensive objects and caching them in a <code>Map</code>. The existing implementation is something like</p>
  
  <pre><code>lock.lock()
  try {
      Foo result = cache.get(key);
      if (result == null) {
          result = createFooExpensively(key);
          cache.put(key, result);
      }
      return result;
  } finally {
      lock.unlock();
  }
  </code></pre>
  
  <p>Obviously this is not the best design when <code>Foos</code> for different <code>keys</code> can be created independently.</p>
  
  <p>My current hack is to use a <code>Map</code> of <code>Futures</code>:</p>
  
  <pre><code>lock.lock();
  Future&lt;Foo&gt; future;
  try {
      future = allFutures.get(key);
      if (future == null) {
          future = executorService.submit(new Callable&lt;Foo&gt;() {
              public Foo call() {
                  return createFooExpensively(key);
              }
          });
          allFutures.put(key, future);
      }
  } finally {
      lock.unlock();
  }
  
  try {
      return future.get();
  } catch (InterruptedException e) {
      throw new MyRuntimeException(e);
  } catch (ExecutionException e) {
      throw new MyRuntimeException(e);
  }
  </code></pre>
  
  <p>But this seems... a little hacky, for two reasons:</p>
  
  <ol>
  <li>The work is done on an arbitrary pooled thread. I'd be happy to have the work
  done on the first thread that tries to get that particular key, especially since
  it's going to be blocked anyway.</li>
  <li>Even when the <code>Map</code> is fully populated, we still go through <code>Future.get()</code> to get
  the results. I expect this is pretty cheap, but it's ugly.</li>
  </ol>
  
  <p>What I'd like is to replace <code>cache</code> with a <code>Map</code> that will block gets <em>for a given key</em> until that key has a value, but allow other gets meanwhile. Does any such thing exist? Or does someone have a cleaner alternative to the <code>Map</code> of <code>Futures</code>?</p>