【发布时间】:2010-09-17 16:24:11
【问题描述】:
我刚刚遇到这个answer in SO,其中提到了 Google 集合 MapMaker 很棒。我浏览了文档,但无法真正弄清楚我可以在哪里使用它。谁能指出一些适合使用 MapMaker 的场景。
【问题讨论】:
我刚刚遇到这个answer in SO,其中提到了 Google 集合 MapMaker 很棒。我浏览了文档,但无法真正弄清楚我可以在哪里使用它。谁能指出一些适合使用 MapMaker 的场景。
【问题讨论】:
这是我使用过的一种方式的快速示例MapMaker:
private final ConcurrentMap<Long, Foo> fooCache = new MapMaker()
.softValues()
.makeComputingMap(new Function<Long, Foo>() {
public Foo apply(Long id) {
return getFooFromServer(id);
}
});
public Foo getFoo(Long id) {
return fooCache.get(id);
}
当在地图上调用get(id) 时,它会返回地图中对应该ID 的Foo,或者它会从服务器检索它、缓存它并返回它。一旦设置好,我就不必考虑这一点。另外,由于我设置了softValues(),缓存无法填满并导致内存问题,因为系统能够从缓存中清除条目以响应内存需求。但是,如果从地图中清除了缓存值,它可以在下次需要时再次向服务器请求它!
问题是,这只是它的一种使用方式。让地图使用强键、弱键或软键和/或值的选项,以及在特定时间后删除条目的选项,让您可以用它做很多事情。
【讨论】:
getFoo和getFooFromServer应该是同一个函数吗?
fooCache.get(id) 时,如果值不在缓存中,就会调用计算映射的Function。如果Function 再次调用getFoo,它将再次尝试调用fooCache.get。也就是说,getFooFromServer() 的代码可以直接在Function 内部定义,而不是作为单独的方法......我只是使用了一个命名方法来明确函数的作用,而无需编写任何实际的假代码调用服务器。
如果您查看SoftReference 和WeakReference 的描述可能会有所帮助。
SoftReference 在缓存中使用非常有用,因为它们会在内存不足时被专门清除。
WeakReference 告诉垃圾收集器它可以收集引用它的对象,只要其他地方没有对它的强引用。这通常用于可以根据需要快速再次查找的内容。
因此,考虑使用 MapMaker 创建一个 ConcurrentMap,其中 softValues 用于缓存,而 weakKeys 用于临时查找表。
编辑:softValues 使用 LRU 策略。
【讨论】: