Making java.util.Iterator.remove() for the iterators for EnumSet more resilient
Neil Richards
neil.richards at ngmr.net
Thu Mar 3 16:41:33 UTC 2011
On 3 March 2011 15:06, Alan Bateman <Alan.Bateman at oracle.com> wrote:
> I think the main thing with this proposal is getting agreement that it is
> the right thing to do. On one hand it avoids the set getting corrupted. On
> the other hand it's masking a problem and really part of a bigger issue.
> This isn't really my area but it kinda feels like we need a run mode or some
> way to enable concurrent modification exceptions so that the developer has
> some chance to fix the real issues.
>
> -Alan.
>
As I previously noted in the discussion [1], the current Javadoc API
for EnumSet explicitly states that ConcurrentModificationException
will never be thrown from its iterator. [2]
Also, Mike observed that other fixes which introduce the possibility
of new ConcurrentModificationExceptions being thrown have previously
been rejected on that basis. [3]
We may all agree that if one was to start from scratch, consistently
throwing CMEs (at least, where it's feasible to detect them) would
probably be the ideal approach.
But given the actual starting point, where existing API documentation
explicits states that CMEs will *never* be thrown from EnumSet's
iterator, and has done so since EnumSet's introduction in Java 5, I
can appreciate there being nervousness about changing that explicit
(EnumSet-iterator-specific) contract with the user/developer at this
point.
Given this nervousness, my suggested change implements the next best
strategy, which is to make the iterator implementation tolerate the
modification without corrupting the underlying EnumSet.
This was, presumably, the behaviour as intended by the original author
of the EnumSet API Javadoc.
(In hindsight, one might disagree with the design choice made, but not
that the design choice *was* made, given its explicit documentation).
To leave the EnumSet iterator's code in its current (unchanged) form,
I would argue, would be the worst possible outcome: It neither
protects the contents of EnumSets from being "gratuitously" corrupted
due to modification from both the iterator and the set (by being
tolerant of this possibility), nor does it alert the developer to the
error they are making.
(I describe the corruption as "gratuitous" because it is so trivial to
avoid for this iterator).
I don't think that having a run-mode to enable CMEs to be thrown in
this case would make things any better for the developer.
What would prompt a developer to run in such a mode?
In practice, I suspect it would merely act as a crutch with which folk
would retrospectively beat the poor developer over the head, once
corrupted EnumSets were detected, possibly (probably?) after their
code is deployed.
If there were agreement to throw CMEs by default, and have a run mode
to disable them, I guess I'd be okay with that. I'm not sure that that
would generally allay the backwards-compatibility concerns
sufficiently for such a solution to be acceptable, however. Also, it
didn't seem like that was the direction that the conversation was
previously heading.
As always, suggestions and guidance on how to progress the resolution
to this problem forward gratefully accepted,
Thanks,
Neil
[1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2011-January/005763.html
[2] http://download.oracle.com/javase/1.5.0/docs/api/java/util/EnumSet.html
[3] http://mail.openjdk.java.net/pipermail/core-libs-dev/2011-February/005799.html
--
Unless stated above:
IBM email: neil_richards at uk.ibm.com
IBM United Kingdom Limited - Registered in England and Wales with number 741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
More information about the core-libs-dev
mailing list