### Question:
ConcurrentLazyMap extends LazyMap<K, V> { @Override public V get(Object key, Factory<? super K, ? extends V> factory) { Utilities.checkNull(factory, "factory"); if (key != null && !getKeyType().isInstance(key)) { return getIfExists(key); } V value = getIfExists(key); if (value != null) { return value; } @SuppressWarnings("unchecked") K k = (K)key; Lock lock = getLock(k); lock.lock(); try { value = getIfExists(key); if (value == null) { value = factory.create(k); getMap().put(k, value); } return value; } finally { lock.unlock(); } } ConcurrentLazyMap(Map<K, V> map, Class<? extends K> keyType);  ConcurrentLazyMap(Map<K, V> map, Class<? extends K> keyType, Factory<? super K, ? extends V> factory); static ConcurrentLazyMap<K, V> create(Map<K, V> map, Class<? extends K> keyType); static ConcurrentLazyMap<K, V> create(Map<K, V> map, Class<? extends K> keyType,
            Factory<? super K, ? extends V> factory); @Override V get(Object key, Factory<? super K, ? extends V> factory); Lock getLock(K key); @Override V put(K key, V value); @Override void putAll(Map<? extends K, ? extends V> m);  }### Answer:
@Test public void testGet() throws InterruptedException, ExecutionException { final AtomicInteger runningCount = new AtomicInteger(); final AtomicBoolean pause5 = new AtomicBoolean(true); final AtomicBoolean pause6 = new AtomicBoolean(true); Map<Integer, Float> map = Collections.synchronizedMap(New.<Integer, Float>map()); final Map<Integer, Float> clm = new ConcurrentLazyMap<Integer, Float>(map, Integer.class, new LazyMap.Factory<Integer, Float>() { @Override public Float create(Integer key) { AtomicBoolean pause = key.intValue() == 5 ? pause5 : pause6; synchronized (pause) { while (pause.get()) { try { pause.wait(); } catch (InterruptedException e) { } } } return Float.valueOf(key.floatValue()); } }); ExecutorService exec = Executors.newFixedThreadPool(3); Future<Float> future5a = exec.submit(new Callable<Float>() { @Override public Float call() { synchronized (runningCount) { runningCount.incrementAndGet(); runningCount.notifyAll(); } return clm.get(Integer.valueOf(5)); } }); Future<Float> future5b = exec.submit(new Callable<Float>() { @Override public Float call() { synchronized (runningCount) { runningCount.incrementAndGet(); runningCount.notifyAll(); } return clm.get(Integer.valueOf(5)); } }); Future<Float> future6 = exec.submit(new Callable<Float>() { @Override public Float call() { synchronized (runningCount) { runningCount.incrementAndGet(); runningCount.notifyAll(); } return clm.get(Integer.valueOf(6)); } }); synchronized (runningCount) { while (runningCount.get() < 3) { runningCount.wait(); } } Assert.assertFalse(future5a.isDone()); Assert.assertFalse(future5b.isDone()); Assert.assertFalse(future6.isDone()); synchronized (pause6) { pause6.set(false); pause6.notifyAll(); } Assert.assertEquals(6f, future6.get().floatValue(), 0f); Assert.assertFalse(future5a.isDone()); Assert.assertFalse(future5b.isDone()); Assert.assertTrue(future6.isDone()); synchronized (pause5) { pause5.set(false); pause5.notifyAll(); } Assert.assertSame(future5a.get(), future5b.get()); Assert.assertEquals(5f, future5a.get().floatValue(), 0f); }