当有人使用MapMaker或WeakHashMaps时,有人可以向我解释一下吗?

我读过许多人非常喜欢Google Guava(collections集)的MapMaker ,但是我看不出它有什么用处。

我已经阅读了javadoc,它说它的行为类似于ConcurrentHashMap 。 它还说new MapMaker().weakKeys().makeMap()几乎总是可以用作WeakHashMap的替代品。

但是,读取ConcurrentHashMap和WeakHashMap的javadoc会让我想知道何时使用它是有用的? 在我看来,你无法保证你在地图中放置的任何东西都会存在,或者我误解了?

……这有点重要。 如果您不想(或不能承受)在内存中保留一个对象,那么弱引用很有用。 请考虑以下用例:您需要将信息与类相关联。 现在,由于您在一个可能重新加载类的环境(例如,Tomcat或OSGi环境)中运行,您希望垃圾收集器能够在它认为安全的情况下尽快回收旧版本的类。 。

实现这一目标的初步尝试可能看起来像

 class ClassAssoc { private final IdentityHashMap,MyMetaData> cache = new ...; } 

这里的问题是:这将永远保留cache成员中的所有类(或者至少,除非它们被手动删除),迫使垃圾收集器无限期地保留它们,包括从类引用的所有内容(静态成员值,类加载器信息) ,…)

通过使用弱引用,只要不存在对它的其他引用(通常是实例),垃圾收集器就可以回收旧版本的类。 另一方面:只要存在这样的引用,就可以保证该值也可以从弱引用对象到达,因此,它是缓存表中的有效键。

将并发和其他暴行添加到图片中,您可以选择MapMaker提供的…

关于MapMaker的事情是,您构建的地图类型有很多选项,这使得这些地图可以用于多种用途。

  • Dirk给出了弱键使用的一个很好的例子。
  • 软值对于缓存很有用,因为您可以在地图中缓存值而不必担心内存不足,因为如果需要内存,系统可以自由地从缓存中逐出条目。
  • 您可以选择在一定时间后过期。 这对缓存也很有用,因为您可能希望在执行昂贵的操作更新之前将某些数据缓存一段特定的时间。
  • 我最喜欢的一件事是制作计算地图。 计算映射使用Function自动检索与给定键相关联的值(如果它尚未在映射中)。 这与软值和/或到期时间很好地结合。 在地图驱逐条目后(由于内存需求或到期),下次请求与该键关联的值时,它将自动被检索并再次缓存在地图中。

WeakHashmap条目将保留在地图中,而某人(地图除外)正在引用该条目。 如果没有其他人在地图上保留对条目的引用,则可以在下一次GC运行时删除该条目。

ConcurrentHashMap是一个可以安全地用于multithreading环境的Map 。 它优于常规Map同步版本,因为并发意味着通常可以使用不同的线程来访问此映射而不会阻塞。