为什么Cache.asMap()与Cache.size()不一致?
在Guava库中,我很困惑为什么Cache.asMap()
与Cache.size()
不一致,除非Cache.cleanUp()
。
Cache cache = CacheBuilder.newBuilder() .expireAfterWrite(1, TimeUnit.SECONDS) .build(); cache.get(...); ... //After some seconds, all entries are expired. //cache.asMap() is EMPTY Map, but cache.size() != 0
所以我的问题是: Cache.asMap()
与Cache.size()
不一致是错误吗? 虽然我注意到Cache.size()
的javadoc是:
/** * Returns the **approximate** number of entries in this cache. */
我猜它可能与并发环境有关。 而Cache.cleanUp()
究竟做了什么?
Guava的缓存是围绕锁定摊销设计的,而cleanUp
方法则强制缓存达到一致状态。 Map.size()
方法是近似值,但可以计算由于到期或参考驱逐而等待删除的条目。 Guava高速缓存中近似值的可见性对于应用程序来说很少有用,它倾向于将高速缓存视为瞬态数据存储。 来自Map的缓存的不同期望导致asMap
方法允许将缓存视为地图,但不喜欢开发人员以这种方式感知它。
StrangleLoop 2011会议幻灯片介绍了缓存的实现细节。 来自Guava缓存的ConcurrentLinkedHashMap
的设计文档也可能引起关注,但描述的方法略有不同。
Ben给出了很好的高层回应。 低级别的回应是:
asMap()
视图可以遍历缓存中的每个元素,因此可以跳过待处理清除的无效条目。 另一方面, size()
预计是一个快速操作,遍历整个缓存只是为了获得更准确的大小估计是愚蠢的。
CacheBuilder
javadocs详细介绍了在各种情况下需要进行的清理(例如expireAfterWrite
,在您的情况下)。