20

如何ConcurrentHashMap在 Java 中获得弱密钥和身份哈希?我认为 Google Guava Collections 可以提供这样的东西,但我可以从标准库中获取它吗?我还有什么其他选择?

4

4 回答 4

14

我认为 Google Guava Collections 可以提供这样的东西,但我可以从标准库中获取它吗?

对此的简短回答是否定的。Java SE 没有实现这种特定的组合。

  • java.util.concurrent.ConcurrentHashMap您可以使用键实例化 a WeakReference,并做一些额外的工作来实现删除损坏引用的映射条目,但这不会给您提供身份哈希语义。

  • java.util.IdentityHashMap您可以用键实例化 a WeakReference,并做一些额外的工作来实现删除损坏引用的映射条目,但这不会给您并发行为。

  • 使用 ajava.util.WeakHashMap不会给你并发或身份哈希。

  • 您可以(理论上)将关键类包装在覆盖自然equalshashcode方法的东西中。但这很可能是不可用的。

  • 我不认为通过覆盖ConcurrentHashMap或中的方法来做到这一点是不可能的IdentityHashMap


也许唯一可行的选择是将关键类和方法更改为基于身份的。但这不适用于“内置”键类型(尤其是键类型)或在应用程序的其他部分需要基于值的等值/哈希码的情况。equalshashcodefinal

于 2013-03-17T02:05:32.423 回答
4

Google Guava 实现似乎是最简单的方法。人们可以使用 初始化所需的地图,new MapMaker().weakKeys().makeMap()并像使用 一样使用java.util.concurrent.ConcurrentHashMap。有关详细信息,请参阅apidoc

于 2015-01-06T23:52:28.837 回答
2

如果你的应用在 spring 框架下(版本是 gt 3.2),你可以考虑使用org.springframework.util.ConcurrentReferenceHashMap. 下面是它的描述:

对键和值都使用软或弱引用的 ConcurrentHashMap。此类可以用作 Collections.synchronizedMap(new WeakHashMap>()) 的替代品,以便在并发访问时支持更好的性能。此实现遵循与 ConcurrentHashMap 相同的设计约束,但支持空值和空键。

注意:引用的使用意味着不能保证放置到地图中的项目随后将可用。垃圾收集器可能随时丢弃引用,因此可能会出现未知线程正在默默地删除条目。

如果未明确指定,此实现将使用软条目引用。

于 2018-11-11T08:27:25.923 回答
1

搜索 ConcurrentWeakIdentityHashMap,你会得到很多例子。我自己写了一个实现,因为我认为 org/ehcache/core/internal/util/ConcurrentWeakIdentityHashMap$WeakReference 的 hashCode 太糟糕了。

ehcache3 示例

我写的例子

Pull Rquest 修复 ehcache3 ConcurrentWeakIdentityHashMap Key hashCode

于 2016-05-24T01:38:23.900 回答