Concurrent collections question 73 of 180 senior
How would you build a thread-safe cache with computeIfAbsent, and what is the trap?
- There is no trap, that is what it is for
- Correct: The mapping function runs while the bin is locked, so a recursive or slow function can deadlock or block every writer to that bin
- It is not atomic
- It cannot store null
computeIfAbsent is the right tool for a memoising cache: exactly one thread computes, everyone else
waits and gets the same value, with no double computation and no check-then-act race.
The trap is what runs under the bin lock. If the mapping function updates the same map, you can get an
IllegalStateException ("recursive update") or, on Java 8, a thread that spins forever inside the call (JDK-8062841). If it
is slow (an I/O call, a remote lookup), every other writer that hashes to the same bin is blocked for
its whole duration, and if two threads compute entries that recursively depend on each other, they
deadlock.
For expensive values the classic alternative is storing a FutureTask or CompletableFuture: insert
the future atomically, then compute outside the lock.
Quiz yourself on Concurrent collections Suggest a correction