如何ConcurrentHashMap
在 Java 中获得弱密钥和身份哈希?我认为 Google Guava Collections 可以提供这样的东西,但我可以从标准库中获取它吗?我还有什么其他选择?
4 回答
我认为 Google Guava Collections 可以提供这样的东西,但我可以从标准库中获取它吗?
对此的简短回答是否定的。Java SE 没有实现这种特定的组合。
java.util.concurrent.ConcurrentHashMap
您可以使用键实例化 aWeakReference
,并做一些额外的工作来实现删除损坏引用的映射条目,但这不会给您提供身份哈希语义。java.util.IdentityHashMap
您可以用键实例化 aWeakReference
,并做一些额外的工作来实现删除损坏引用的映射条目,但这不会给您并发行为。使用 a
java.util.WeakHashMap
不会给你并发或身份哈希。您可以(理论上)将关键类包装在覆盖自然
equals
和hashcode
方法的东西中。但这很可能是不可用的。我不认为通过覆盖
ConcurrentHashMap
或中的方法来做到这一点是不可能的IdentityHashMap
。
也许唯一可行的选择是将关键类和方法更改为基于身份的。但这不适用于“内置”键类型(尤其是键类型)或在应用程序的其他部分需要基于值的等值/哈希码的情况。equals
hashcode
final
Google Guava 实现似乎是最简单的方法。人们可以使用 初始化所需的地图,new MapMaker().weakKeys().makeMap()
并像使用 一样使用java.util.concurrent.ConcurrentHashMap
。有关详细信息,请参阅apidoc。
如果你的应用在 spring 框架下(版本是 gt 3.2),你可以考虑使用org.springframework.util.ConcurrentReferenceHashMap
. 下面是它的描述:
对键和值都使用软或弱引用的 ConcurrentHashMap。此类可以用作 Collections.synchronizedMap(new WeakHashMap>()) 的替代品,以便在并发访问时支持更好的性能。此实现遵循与 ConcurrentHashMap 相同的设计约束,但支持空值和空键。
注意:引用的使用意味着不能保证放置到地图中的项目随后将可用。垃圾收集器可能随时丢弃引用,因此可能会出现未知线程正在默默地删除条目。
如果未明确指定,此实现将使用软条目引用。
搜索 ConcurrentWeakIdentityHashMap,你会得到很多例子。我自己写了一个实现,因为我认为 org/ehcache/core/internal/util/ConcurrentWeakIdentityHashMap$WeakReference 的 hashCode 太糟糕了。
Pull Rquest 修复 ehcache3 ConcurrentWeakIdentityHashMap Key hashCode