Skip to main content

javadoc on java.util.WeakHashMap

5 replies [Last post]
alexlamsl
Offline
Joined: 2004-09-02

I thought it might be wise to have a wider consensus here before formally reporting it via JDK Bug Parade.

The description of WeakHashMap contains the following:

... In particular, even if you synchronize on a WeakHashMap instance and invoke none of its mutator methods, it is possible for ...

(Editted in terms of points for ease of view ;) )

1) the size method to return smaller values over time

2) the isEmpty method to return false and then true

3) the containsKey method to return true and later false for a given key

4) the get method to return a value for a given key but later return null

5) the put method to return null and the remove method to return false for a key that previously appeared to be in the map

6) successive examinations of the key set, the value collection, and the entry set to yield successively smaller numbers of elements.

The problem is on points (3) and (4) - if I'm holding a reference to the very key that I'm testing against the Map, how is it possible for the relevant Entry to be discarded between 2 retrieval calls if no mutator methods are called in between?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
tackline
Offline
Joined: 2003-06-19

I'm not sure how you are expecting WeakHashMap to prevent weak references clearing at times inconvenient for the client. To do so would require reading out all of the WeakReference's referents. Also there is no way for an object to exactly detect when it becomes the subject of a synchronize lock, or similar from java.util.concurrent.

Keeping a reference to the actual key object (unless obtained through finaliser resurrection) does keep the entry in place. The key is in ordinary use and not discarded.

You can prevent any automatic modifications to the map by keeping hold of an array returned by weakMap.keySet().toArray().

What's really missing is a ConcurrentWeakIdentityHashMap. I believe there has been talk of a WeakIdentityHashMap/IdentityWeakHashMap, which WeakHashMap should have been in the first place, but I haven't seen anything as yet.

ajsutton
Offline
Joined: 2003-08-07

You don't nessecarily have a reference to the same object, you may have a reference to an object that is .equals() to the key but not == to it.

For example, think of a WeakHashMap where the keys are Strings, you could do:

weakHashMap.put(new String("My String"), "My Value");

and then later:

weakHashMap.get(new String("My String"))

and get null. The example is obviously bad code but you could have wound up with the same string from reading user input, concatentation or any number of other ways such that it is a different object but still .equals().

alexlamsl
Offline
Joined: 2004-09-02

A passage from the same page:

[i]This class is intended primarily for use with key objects whose equals methods test for object identity using the == operator. Once such a key is discarded it can never be recreated, so it is impossible to do a lookup of that key in a WeakHashMap at some later time and be surprised that its entry has been removed.[/i]

So what do you think? :)

ajsutton
Offline
Joined: 2003-08-07

While the class is intended only for == type comparisons, it is regularly used with other types as well - often with buggy consequences which is precisely why the JavaDoc points out that a key might be present one minute and missing the next.

alexlamsl
Offline
Joined: 2004-09-02

I see - right, gotcha ;)

So the documentation is indeed correct; though I would incline to be slightly more specific rather than making over-statements, but then I guess when people code they usually under-estimate the effects of these singularities anyway (until something is broken, that is =P)