咖啡因的行为 Cache.asMap 次观看

Behaviour of Caffeine Cache.asMap views

Javadoc 说:

Returns a view of the entries stored in this cache as a thread-safe map. Modifications made to the map directly affect the cache.

我缺少的是关于访问视图是否影响准入和逐出策略的信息。根据 this old related issue 它没有:

In Guava's CacheBuilder we added the asMap() view specifically to allow bypassing the cache management routines. There a cache.asMap().get(key) is a peek operation.

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

例如,我发现自己使用 cache.asMap().putIfAbsent,因为我的值是键的函数,因此替换它们毫无意义。如果条目不存在,我希望它能像 cache.put 一样工作。

这是 Guava 的 Map.get 最初讨论的一部分,但可能是个糟糕的主意,沟通不畅,最终失败了。一个合理的原因是用户不期望大多数 Map 操作的副作用,MapMaker 随着计算映射的改变而因此破坏了 equals 方法。

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

然而,无论好坏,一方面确实存在。与Cache.getIfPresent不同,Map.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 方法不会。值得庆幸的是,这是一个足够小的细节,没有引起很多问题,如果认为值得,可以进行更改。