[concurrency-interest] Bug in ConcurrentHashMap
Fri, 21 Nov 2003 13:26:41 -0800
It is fine to add that test case to the tests, but keep in mind that it is very
dependent on the sizing and hash algorithms that are currently used in the map
in order to get a reference to an entry that would be cloned.
Also, it was not strictly necessary to remove the key from a separate thread, of
course, but I wanted it to reflect a more believable scenario.
Use cases for putIfPresent come up when the existence of a key in the map has
significance beyond what the value associated with the key is. One such use case
is when the map is used for caching data from a relational database and the
presence of the key in the map may provide a hint that the corresponding row
exists in the database*, or it may provide the ability to enumerate the names of
all known documents, etc., without necessarily having the value in the map at
the moment. To free up memory in the cache you may want to replace the value in
the map with a placeholder indicating that the value is now invalid and needs to
be retrieved from the database again the next time it is requested (let's call
the placeholder object INVALID). However, you don't want to lose the
information that the key exists. So you want to put(key, INVALID). But this
should not create a new key in the map if that key was just legitimately removed
from the map (and the database, e.g. by another thread). So in this case you
would want call putIfPresent(key, INVALID). I'm sure there are other ways of
implementing this use case, but this is a case where a putIfPresent method would
indeed be useful.
I have other, more complicated use cases where putIfPresent would be useful, but
hopefully this simple one suffices to make the point.
Thanks for fixing the setValue bug so quickly, by the way!
* The presence of the key might provide a hint as to whether a CREATE or UPDATE
is necessary when synchonizing with a RDBMS
Doug Lea wrote:
> A better way to do this was to apply the tactics we used in
> IdentityHashMap of making EntrySet entries mere forwarders (but still
> more efficiently handling the more common keySet and Values
> iterators). As is now checked in.
> Eric: Is it OK fow us to add your test case to JSR166 tests?
> I didn't answer before:
>>Which leads me to another comment. It would be useful to have a "putIfPresent"
>>method on ConcurrentMap in addition to the putIfAbsent that is already there,
>>for the case where you require the entry to already exist when replacing a
> Can you give a good use case? I can't think of any.