Of course, you can make atomic using the lock, imagine the most primitive case: you have a global lock around your entire function, then everything is single-threaded and, therefore, thread-safe. I assume that either they had in mind something else, or there was a general misunderstanding.
Your code can even be improved using the putIfAbsent method for ConcurrentHashMap as follows:
public V compute(final A arg) throws InterruptedException { Future<V> f = cache.get(arg); if (f == null) { final Callable<V> eval = new Callable<V>() { public V call() throws InterruptedException { return c.compute(arg); } }; final FutureTask<V> ft = new FutureTask<V>(eval); final Future<V> previousF = cache.putIfAbsent(arg, ft); if (previousF == null) { f = ft; ft.run(); } else { f = previousF;
f at the end will be either the previous value that was added between or the initial value, and the potential cost of the additional creation of Callable, but the call for calculation is not performed more than once.
Twothe
source share