PullThroughCache implements Map<K, V> { @Override @SuppressWarnings("unchecked") public V get(Object key) { PullThroughReference<K, V> valueReference; while ((valueReference = (PullThroughReference<K, V>) garbages.poll()) != null) { K valueKey = valueReference.getKey(); if (cache.remove(valueKey, valueReference)) { latches.remove(valueKey); LOGGER.debug( "Removing [{}]; Cache size=[{}]", valueKey, cache.size()); } } if (!keyClass.isInstance(key)) { return null; } K typedKey = (K) key; V value = null; while (true) { valueReference = cache.get(typedKey); if (valueReference != null) { value = valueReference.get(); if (value != null && !isExpired(typedKey, valueReference.getProduceDate())) { return value; } } if (latches.putIfAbsent(typedKey, new ThreadAwareLatch()) == null) { LOGGER.debug("Producing [{}]", typedKey); try { V produced = produce(typedKey); valueReference = referenceFactory.create(garbages, typedKey, produced, new Date()); cache.put(typedKey, valueReference); return produced; } catch (Exception ex) { throw ex instanceof RuntimeException ? (RuntimeException) ex : new PullThroughProductionException(typedKey, ex); } finally { ThreadAwareLatch latch = latches.remove(typedKey); if (latch != null) { latch.countDown(); } } } else { ThreadAwareLatch latch = latches.get(typedKey); if (latch != null) { if (latch.isFromCurrentThread()) { throw new PullThroughDeadlockException(typedKey); } LOGGER.debug("Waiting on [{}].", typedKey); try { latch.await(); } catch (InterruptedException ex) { } } valueReference = cache.get(typedKey); if (valueReference != null) { value = valueReference.get(); if (value != null) { return value; } } } } } PullThroughCache(Class<?> keyClass, Class<? extends PullThroughReferenceFactory> factoryClass);  PullThroughCache(Class<?> keyClass);  PullThroughCache(); boolean isProduced(K key); Date getLastProduce(K key); @Deprecated Date getLastProduceDate(K key); synchronized void invalidate(); synchronized void invalidate(K key); @Override void clear(); @Override boolean containsKey(Object key); @Override boolean containsValue(Object value); @Override Set<Map.Entry<K, V>> entrySet(); @Override @SuppressWarnings("unchecked") V get(Object key); @Override boolean isEmpty(); @Override Set<K> keySet(); @Override V put(K key, V value); @Override void putAll(Map<? extends K, ? extends V> map); @Override V remove(Object key); @Override int size(); @Override Collection<V> values(); @Override String toString();  }
@Test public void get() { assertEquals("A1", cache.get("a")); }
@Test public void get_twice() { cache.get("a"); assertEquals("A1", cache.get("a")); }