54

Collections.synchronizedMap()可以在不使用同时保持并发正确性的情况下重写以下代码吗?

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

即有没有来自 java.util.concurrent 的东西可以用来代替?请注意,仅替换为

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

显然行不通

4

7 回答 7

40

GuavaCacheBuilder类允许您轻松地做到这一点。

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

请注意,这会将关键相等语义更改为,==.equals()不是在您使用实例的情况下无关紧要,Class但这是一个潜在的陷阱。

于 2010-02-13T00:38:56.953 回答
22

我不相信有。事实上,javadoc 建议使用 Collections.synchronizedMap()

“像大多数集合类一样,这个类是不同步的。可以使用 Collections.synchronizedMap 方法构造一个同步的 WeakHashMap。”

于 2010-02-13T00:34:20.580 回答
2

咖啡因是番石榴缓存的热门竞争对手。

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

用法:

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
 .weakKeys()
 .weakValues()
 .build(key -> createExpensiveGraph(key));
于 2017-10-13T16:04:25.640 回答
0

将 WeakHashMap 包装在同步映射中是否仍然可以正常工作,因为垃圾收集器可以随时直接修改弱引用,绕过同步映射包装器?我认为 WeakHashMap 只能在单线程模型中真正起作用。

如上所述,在https://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html的 WeakHashMap 文档特别指出:

“可以使用 Collections.synchronizedMap 方法构建同步的 WeakHashMap”

这对我来说意味着这种技术必须与垃圾收集器的行为协同工作(除非文档有问题!)

于 2017-02-17T10:23:40.633 回答
0

ClassValue 如果您使用的是 Java 7 及更高版本,则使用https://docs.oracle.com/javase/7/docs/api/java/lang/ClassValue.html以线程安全的方式解决此用例 如果您需要的使用remove,仔细考虑并发性并彻底阅读文档。

如果您使用的是 Java 6 或更低版本。不,您必须同步 WeakHashMap。

于 2018-04-04T09:21:40.213 回答
0

如果您的类路径中已经有 Spring 框架,那么一种选择是ConcurrentReferenceHashMap

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/util/ConcurrentReferenceHashMap.html

您可以选择使用引用或引用(对于键和值)。

于 2021-08-13T13:09:13.913 回答
-1

将 WeakHashMap 包装在同步映射中是否仍然可以正常工作,因为垃圾收集器可以随时直接修改弱引用,绕过同步映射包装器?我认为 WeakHashMap 只能在单线程模型中真正起作用。

于 2012-03-05T19:18:08.540 回答