Is there java.util.concurrent equivalent for WeakHashMap?

帅比萌擦擦* 提交于 2019-11-27 01:19:05

问题


Can the following piece of code be rewritten w/o using Collections.synchronizedMap() yet maintaining correctness at concurrency?

Collections.synchronizedMap(new WeakHashMap<Class, Object>());

i.e. is there something from java.util.concurrent one can use instead? Note that merely replacing with

new ConcurrentHashMap<Class, Object>(new WeakHashMap<Class, Object>()));

obviously won't work


回答1:


Guava's CacheBuilder class allows you to do this easily.

CacheBuilder.newBuilder().weakKeys().build()

Note that this changes key equality semantics to be == instead of .equals() which will not matter in your case of using Class instances but is a potential pitfall.




回答2:


I don't believe there is. In fact the javadoc suggests using Collections.synchronizedMap()

"Like most collection classes, this class is not synchronized. A synchronized WeakHashMap may be constructed using the Collections.synchronizedMap method."




回答3:


Cafeine is a popular competitor of Guava cache.

- keys automatically wrapped in weak references
- values automatically wrapped in weak or soft references

usage:

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
 .weakKeys()
 .weakValues()
 .build(key -> createExpensiveGraph(key));



回答4:


Does wrapping the WeakHashMap in a synchronized map still work correctly for what you want to do, since the garbage collector can modify the weakreferences directly at anytime, bypassing the synchronized map wrapper? I think WeakHashMap only truly works in a single threaded model.

As mentioned above, the documentation for WeakHashMap at https://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html specifically says:

"A synchronized WeakHashMap may be constructed using the Collections.synchronizedMap method"

Which implies to me that this technique must work in tandem with the garbage collector's behavior (unless the documentation is buggy!)




回答5:


If you are using Java 7 and above, this use case is solved in a thread-safe manner with ClassValue https://docs.oracle.com/javase/7/docs/api/java/lang/ClassValue.html If you require the use of remove, think carefully about concurrency and read the doc thoroughly.

If you are using Java 6 or below. No, you have to synchronize a WeakHashMap.




回答6:


Does wrapping the WeakHashMap in a synchronized map still work correctly for what you want to do, since the garbage collector can modify the weakreferences directly at anytime, bypassing the synchronized map wrapper? I think WeakHashMap only truly works in a single threaded model.



来源:https://stackoverflow.com/questions/2255950/is-there-java-util-concurrent-equivalent-for-weakhashmap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!