Caffeine Cache.asMap视图的行为

时间:2018-01-07 16:15:13

标签: java caching caffeine

Javadoc说:

  

将此缓存中存储的条目视图作为线程安全映射返回。对地图所做的修改会直接影响缓存。

我缺少的是有关访问视图是否会影响入场和逐出政策的信息。根据{{​​3}},它没有:

  

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

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

例如,我发现自己使用cache.asMap().putIfAbsent因为我的值是键的功能,所以替换它们是毫无意义的。如果条目不存在,我希望它与cache.put完全一致。

1 个答案:

答案 0 :(得分:1)

这是对番石榴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.

对于其他Java 8方法,这在Caffeine中略有修改,

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

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