Okay you have incited me to throw in my 2c :) I think the CME issue has been raised a number of times in the past (and if the below doesn't agree with what I've said in the past Hey! It's a brand new day! ;-) )

But first, Mike the missing spaces are creeping back in "if(xxx)" :)

For Map I don't think looking for external concurrent modification and throwing CME is necessary or worthwhile. These are not thread-safe methods. That covers:
 - remove, replace

and it implies that putIfAbsent should not check for or throw CME.

For compute* and merge it is possible that the computation function modifies the Map - unlikely perhaps but possible - so CME here seems more reasonable. (As for forEach, replaceAll etc.)

I fully agree with removing the retry loops in these non-concurrent implementations.

That said it makes ConcurrentMap somewhat different to Map as it never throws CME even if it was an internal mutation.

Aside: do you still need to re-list every unchecked exception when overriding (i.e. @throws foo {@inheritDoc}) to get them to show up in the subtype docs? I can't tell if this has been forgotten or whether the ConcurrentMap methods truly will never throw such exceptions.

Cheers,
David
-----

On 16/10/2013 2:38 AM, Paul Sandoz wrote:

On Oct 15, 2013, at 6:25 PM, Mike Duigou <mike.dui...@oracle.com> wrote:


On Oct 14 2013, at 02:32 , Paul Sandoz wrote:

Virtually all the cases where CME is thrown in the "new" Map defaults are the 
points where previously the implementation would have looped/retried.


For the cases where no function values are passed it has very limited value, we 
know it is effectively useless for non-current collections being modified 
concurrently.

Understood. The alternative would be to GIGO these situations, return and 
ignore them.


Yeah, unnecessarily complicates the code.

It does detect legitimate errors and it makes me uncomfortable to just ignore 
them.


It is not deterministic.

Does HashMap's implementation of putIfAbsent throw a CME?


For the cases where a function value is passed and it modifies the map then it could have 
some value. But i wonder, for any non-looping function value accepting method on Map 
(anything other than forEach/replaceAll), whether it is just simpler to state: "if a 
function value modifies the entry under computation then this method may return incorrect 
results`".

Modification of any other entry may have the same result.

Yes, although IIUC modification, by the function value, of other entries will 
not interfere with that of operating on the entry under computation. A more 
general recommendation is the function values should be stateless.


I suspect that modification by some other thread is as likely to be a problem 
as modification by the function.


And under concurrent modification we cannot deterministically detect. CME in 
the non-concurrent collections is only useful for detecting serial modification 
due to inversion of control, and in these particular cases it is really very 
limited as to what it detects.

True, but it generally doesn't impose any extra cost. The error detection 
happens as a side effect of necessary operations.


There cost to code complexity. I would argue that additional complexity is not 
worth it given the limits of what can be detected.

I guess you know my opinion: remove 'em. So i will be silent for a bit and see 
if anyone else speaks up :-)

Paul.

I'd like to bring this set of changes to conclusion as soon as possible.

Mike


Reply via email to