dl at cs.oswego.edu
Fri Oct 7 06:41:55 EDT 2011
On 10/06/11 17:39, David M. Lloyd wrote:
> -- we add some
>> time/space overhead to entrySet operations just to imperfectly
>> reinforce the questionable intuition that methods operate
>> directly on internal Entry objects that don't actually exist
>> (and need not actually exist wrt any other aspects of Map specs).
> But if the Entry actually *did* reflect the actual physical entry, then the
> contract for the Entry interface makes a lot more sense. You can retrieve the
> key always, and the value if it hasn't been removed (if it has you could give
> IllegalStateException as is allowed by spec).
We considered and rejected this approach back in JDK5 when deciding
upon iterator semantics for concurrent collections. If you allow
hasNext() to lie, claiming that an element exists but then throwing
an exception in next() because it no longer exists, then most
client iterator usages break. So instead we ensure that if
hasNext saw a valid element, then it is snapshotted as the one
returned in next(). Since these elements can concurrently come
and go at any time, receiving this (weakly consistent) snapshot
is as much as you can expect anyway. Even if you exported
a "live" entry, it could disappear as soon as client reads it
but before it acts upon it.
The underlying problem is that the non-atomic hasNext()/next()
pairing in Iterator is inherently concurrency-hostile.
But we didn't want to replace it with something else.
However, with upcoming lambdas and bulk operations, I'm
considering creating a variant of CHM that does not support
iterators at all, but instead several variants of
method forEach(entry -> action) etc.
More information about the Concurrency-interest