studdugie at gmail.com
Wed Oct 5 09:31:06 EDT 2011
+1 Fix it
On Wed, Oct 5, 2011 at 9:11 AM, Doug Lea <dl at cs.oswego.edu> wrote:
> I'm still contemplating changes in handling null-returns
> in the new compute methods. But in the mean time, here
> is another tiny corner-case issue that is handled differently
> in ConcurrentHashMapV8 than in the existing j.u.c version.
> I consider it just a misfeature-fix, but Joe Bowbeer remains
> nervous about it, so urged me to post and solicit reaction.
> This takes a fair amount of context to set up:
> The Set<Map.Entry> you get from map.entrySet() has always
> had some problematic specs, mainly because they are
> based on those of Map.Entry. When you have a Map.Entry,
> you don't know whether it is mutable vs immutable
> because setValue is an optional operation. And in some
> cases, you don't whether setValue actually updates
> the map you got the entry from or just updates an
> unbound Map.Entry object.
> While it would be nice to better specify some of this,
> the current Map-related specs are phrased in such a way
> that implementations can normally do what users expect.
> The main intent of setValue is to support only
> one use case: iterating through entries one-by-one
> and changing some of the mapped values in the absence
> of any modifications by other threads. ConcurrentHashMap
> (both the existing and V8 versions) supports this use case
> in the expected way -- which of course can have surprising
> effects if other threads ARE modifying the map while
> you are doing this. But we don't go so far as
> to disable the method because of this.
> However, the write-through nature of setValue
> (i.e., to actually change the mapped value in
> the map) conflicts with the intent of the
> entrySet.toArray() method. Even though the
> Collection.toArray() spec doesn't explicitly
> say so, users expect it to return an independent
> copy of the elements, in array form. For example,
> you would be surprised and unhappy if you did
> Object a = myArrayList.toArray();
> a = 17;
> and then found out that this caused myArrayList.get(0)
> to also now return 17.
> In the case of ConcurrentHashMap, this means that the
> kind of Entry you get for the elements of entrySet.toArray
> should NOT write back to the map you got them from.
> In other words:
> Object a = myMap.entrySet().toArray();
> should not change myMap.get(keyFor0) to return 17.
> However, the existing j.u.c version does so. This was
> changed to the safer non-write-through form for V8.
> The original/existing behavior was mainly just due to
> oversight -- it would have been different to begin with
> if anyone had noticed this issue of establishing a
> persistent aliasing path (unlike the transient path
> available in one-by-one iteration).
> In general the interactions of loose specs for both
> Map.Entry and Collection.toArray mean that you can't
> count on very much here, and it turns out that different
> Maps do different things. For ConcurrentHashMap, we'd
> like it to do the most sensible thing, at least in
> future versions. However, because the specs are loose,
> we cannot claim that this is a bug-fix; it is just
> a mis-feature fix.
> To me, fixing the mis-feature is more important
> than retaining pure compatibility for a usage
> that probably didn't do what people expected anyway.
> But if you've ever done anything relying on the old j.u.c
> behavior, could you let us know? Thanks!
> Concurrency-interest mailing list
> Concurrency-interest at cs.**oswego.edu <Concurrency-interest at cs.oswego.edu>
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Concurrency-interest