2

Javadoc说:

以线程安全映射的形式返回存储在此缓存中的条目的视图。对地图的修改直接影响缓存。

我缺少的是有关访问视图是否会影响接纳和驱逐政策的信息。根据这个旧的相关问题,它没有:

在 Guava 的 CacheBuilder 中,我们专门添加了 asMap() 视图以允许绕过缓存管理例程。cache.asMap().get(key) 是一个 peek 操作。

这肯定是有道理的。OTOH 视图提供了许多直接不可用的操作,用户可能会想使用它们,希望他们像直接操作一样更新访问统计信息。

例如,我发现自己使用cache.asMap().putIfAbsent的是键的功能,所以替换它们是没有意义的。我希望它的工作方式cache.put与条目不存在的情况完全相同。

4

1 回答 1

2

这是 Guava 最初讨论的一部分Map.get,但很可能是一个糟糕的想法,沟通不畅,最终失败了。Map一个合理的原因是由于用户不期望大多数操作会产生副作用,这会MapMaker随着计算地图而改变,从而破坏了该equals方法。

回想起来,将任何Map方法视为不同的方法都违反了最小惊讶原则,并且不是很有用。这可能是在实施过程中实现的,但由于团队不连贯和细节丰富,我忘记了这一点。我们还决定了这样一个原则,即用户不需要知道策略是如何工作的,或者使用配置旋钮来影响它们的实施,如果安静get就会暴露出来。

然而,无论好坏,一个方面确实仍然存在。不像Cache.getIfPresentMap.get不会记录命中率统计。同样对于所有其他Map操作,它们可能会选择不更新CacheStats。在番石榴中,这表示为,

No stats are modified by operations invoked on the asMap view of the cache.

这在 Caffeine 中针对其他 Java 8 方法稍作修改,

No stats are modified by non-computing operations invoked on the 
asMap view of the cache.

可能不应该发生这种退出统计的情况,但这是原始讨论的剩余部分。这是一个微妙的细节,它可能不会被完全尊重,因为我相信 Guava 添加的计算Map方法不会。值得庆幸的是,这是一个足够小的细节,没有引起很多问题,如果认为值得,可以更改。

于 2018-01-07T19:16:09.897 回答