Hi,

Here is an updated treatment of computeIfAbsent():

http://cr.openjdk.java.net/~bchristi/8071667/webrev.1/

There's a webrev, as well as built docs for Map[1], ConcurrentMap[2], and HashMap[3] (and I now realize there should be Hashtable as well).

I've made use of @implSpec and friends in a way I thought was sensible (though things could be arranged differently - I can see where some might find the additional headings in the rendered JavaDoc a little distracting ). Let me know what you think.

Thanks,
-Brent

1. http://cr.openjdk.java.net/~bchristi/8071667/webrev.1/docs/api/java/util/Map.html#computeIfAbsent-K-java.util.function.Function-

2. http://cr.openjdk.java.net/~bchristi/8071667/webrev.1/docs/api/java/util/concurrent/ConcurrentMap.html#computeIfAbsent-K-java.util.function.Function-

3. http://cr.openjdk.java.net/~bchristi/8071667/webrev.1/docs/api/java/util/HashMap.html#computeIfAbsent-K-java.util.function.Function-


On 3/11/15 2:05 AM, Paul Sandoz wrote:

On Mar 11, 2015, at 12:34 AM, Brent Christian <brent.christ...@oracle.com> 
wrote:

Hi, Paul

On 3/10/15 8:29 AM, Paul Sandoz wrote:

On the Map.compute* methods.

Perhaps we can reuse similar language to that we added for Matcher:

* The mapping function should not modify this map during computation.
* This method will, on a best-effort basis, throw a
* ConcurrentModification if such modification is detected.

It's tempting to place the second sentence on the @throws
ConcurrentModificationException as i believe will not show up for
methods on ConcurrentMap, so keeps it somewhat contained
documentation wise.

The language in Matcher is nice, and we can use it in HashMap.  But the default 
code in Map.compute* won't throw a CME (no iteration).

That's ok, we can call that out if necessary in the @implSpec.


  For the compute* methods in the Map interface, I think we should stick to 
recommending against modifying the Map during the computation,

Yes.


and encouraging implementing classes to check for CME.


Yes. My suggestion was to try and push much of the CME-related specification 
onto the @throws CME docs. That way less of this will appear on ConcurrentMap 
where CME does not make sense.


In Map/HashMap, there are already two methods that accept lambdas
and throw a CME: forEach(BiConsumer) replaceAll(BiFunction)

(The default code does not throw a CME ifitems are added).

Right, although the iterator might still be fail-fast.

Ahh - I needed to update my test code (if a Map only has a single entry, the iterator 
doesn't CME when items are added because a second "iteration" never happens to 
detect the changed modCount).  A Map with >= 2 entries is needed for the default code to 
CME due to items being added during forEach()/replaceAll().


Yeah, it's all "best-effort".

Paul.

Reply via email to