ConcurrentHashMap/ConcurrentMap/Map.compute (original) (raw)

Brian Goetz brian.goetz at oracle.com
Fri Dec 7 06:22:17 PST 2012


Let's back up. I don't understand the premise of the question.

CM already has methods putIfAbsent and friends, which are currently abstract in CM, and will remain abstract in CM even though Map will acquire them with non-atomic defaults. No problem so far.

CM will now acquire some NEW methods, taking lambdas. Like:

computeIfAbsent(K, K->V)

The following default implementation is atomic because putIfAbsent is already atomic in CM:

computeIfAbsent(K key, K->V fn) { if (!containsKey(key)) putIfAbsent(key, fn.apply(key)); }

What it doesn't do is guarantee that the generating function is called exactly once, or that the result of that generating function is not discarded.

The better version implemented by CHM will have better properties -- that the function is called exactly once and the result is never discarded. But I don't see where the non-atomicity comes from?

So, to re-ask:

Should the cases of existing ConcurrentMap methods and the new function-accepting methods work differently? Suppose someone calls computeIfAbsent on a JDK7-compliant (but non-JDK) ConcurrentMap that doesn't have an explicit override. They would get the non-atomic version. And this is considered OK according to the the specs as I wrote them. But still surprising to at least some users.



More information about the lambda-libs-spec-experts mailing list