Java Concurrency Interview

Live coding puzzles question 176 of 180 senior

Write a thread-safe lazily initialised cache where each key is computed once.

computeIfAbsent is the one-liner and the right first answer:

V get(K key) {
    return cache.computeIfAbsent(key, this::compute);
}

Exactly one thread computes, the others wait, no duplicate work. Then volunteer the caveat, because it is what the question is for: the function runs while the bin is locked, so a slow or recursive computation blocks other writers to that bin or throws IllegalStateException.

The classic alternative from Java Concurrency in Practice keeps the lock short by storing a future:

Future<V> future = cache.get(key);
if (future == null) {
    FutureTask<V> task = new FutureTask<>(() -> compute(key));
    future = cache.putIfAbsent(key, task);
    if (future == null) {
        future = task;
        task.run();          // compute outside any map lock
    }
}
return future.get();

Mention cache eviction and the failure case too: a failed computation must be removed, or you have cached an exception forever.

puzzle chm futures

Quiz yourself on Live coding puzzles Suggest a correction