On 16/10/2013 8:03 PM, Paul Sandoz wrote:
On Oct 16, 2013, at 6:41 AM, David Holmes <david.hol...@oracle.com> wrote:
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.
HashMap.compute*/merge methods do not throw CME either. I suppose those methods
could and do so beyond that of only the entry under computation. I think this
really points to the fact that, for non-traversal, only concrete
implementations are capable of reliably detecting a CME and therefore it's best
to leave it up to those implementations should they choose to do so.
Perhaps HashMap's implementations should throw CME?
But the possibility of CME has to be allowed for in the spec of the
interfaced methods regardless.
David
Paul.
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
-----