Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am using a WeaekHashMap to implement a Cache. I am wondering if I am iterating over the keys of this map, and at the same time garbage collector is actively removing keys from this map, would I receive a ConcurrentModificationException ? I do not think so, because as far as I understand, concurrentmodificationexception happens because of bugs in the application code where the developer forgot to understand that the same map is shared/used by other threads and in this case, it should not happen. But wondering how would JVM handle this when WeakHashMap is not synchronized ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
216 views
Welcome To Ask or Share your Answers For Others

1 Answer

As bkail said, when GC "removes" an entry from a WeakHashMap it is not going to cause a concurrent modification. In reality the GC collects the underlying object by there is a hard reference to WeakReference object (that holds the real key) itself. Therefore, the real object (the reference object) that is directly referenced by the map is not collected so the map does not change until one of your threads calls a method in this map. At that time the map checks the reference queue from the GC and finds all keys that have been collected and removes them from the map - so the actual changes to the map structure occurs on one of your threads.

In thinking of this then there may be one case where you may get a concurrent modification in such a map that you would not get in another kind of map - if you put a key that already exists or call a getter method. But really, in a concurrent application you should be locking around these calls anyway so you would have a really concurrent access bug in your program.

That being said in answer to your question, you really should not use WeakHashMap for a cache (even if you were talking about caching keys). In a cache you don't want your values 'magically' disappearing when the values are no longer referenced. Typically you want them to disappear when there is a certain maximum number (something like Apache collections LRUMap) or released on memory demand.

For the later, you can use a map with a SoftReference (Apache collections provides a ReferenceMap that allows you to specify the kind of reference for either the key or value). A soft reference is specified to only be released based on memory pressure - a weak reference on the other hand has to do more with GC recognizing that there are no hard reference remaining to the object and can release it at any time. Of course, how a soft reference really works is also dependent on the JVM implementation.

EDIT: I reread your question and want to address one other point. Because the actual modifications occur to the WeakHashMap internal structures on your own thread, if you only use this map in a single thread you do not need to synchronize any method calls. This behavior is no different than any other Map.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...