5

假设我有一个Cache这样定义的:

private static Cache<String, Long> alertsUIDCache = CacheBuilder.newBuilder().
           expireAfterAccess(60).build();

从我读到的(如果我错了,请纠正我):

如果在 0:00 写入值Cache,则应在 60 秒后将其移至“准备好被驱逐”状态。实际从 中删除值Cache将在下一次缓存修改时发生(缓存修改到底是什么?)。那正确吗?

另外,我不确定方法invalidateAll()cleanUp()方法之间有什么区别,有人可以提供解释吗?

4

1 回答 1

9

此链接的第一部分: Guava 如何在其 CacheBuilder 中过期条目?

我将专注于expireAfterAccess,但 expireAfterWrite 的过程几乎相同。就机制而言,当您在 CacheBuilder 中指定expireAfterAccess时,缓存的每个段都会为条目维护一个链表访问队列,按照从最近最少访问到最近访问的顺序排列。缓存条目实际上是链表中的节点,所以当一个条目被访问时,它会将自己从访问队列中的旧位置移除,并将自己移动到队列的末尾。

第二部分:来自此链接:Guava CacheLoader - 如果设置了 expireAfterWrite 和 expireAfterAccess ,则无效不会立即使条目无效

invalidate应该立即删除该条目——而不是等待另一个查询——并且应该强制在对该键的下一个查询中重新加载该值。

cleanUp:执行缓存所需的任何挂起的维护操作。究竟执行了哪些活动——如果有的话——是依赖于实现的。

来自番石榴文件https ://github.com/google/guava/wiki/CachesExplained

显式删除

在任何时候,您都可以显式地使缓存条目无效,而不是等待条目被驱逐。可以这样做:

individually, using Cache.invalidate(key)
in bulk, using Cache.invalidateAll(keys)
to all entries, using Cache.invalidateAll()

什么时候进行清理?

使用 CacheBuilder 构建的缓存不会“自动”执行清理和逐出值,也不会在值过期后立即执行,或任何类似的操作。相反,它在写入操作期间执行少量维护,或者如果写入很少,则在偶尔的读取操作期间执行。

原因如下:如果我们想连续进行Cache维护,就需要创建一个线程,它的操作会和用户操作竞争共享锁。此外,某些环境会限制线程的创建,这会使 CacheBuilder 在该环境中无法使用。

相反,我们将选择权交给您。如果您的缓存是高吞吐量的,那么您不必担心执行缓存维护以清理过期条目等。如果您的缓存很少写入并且您不希望清理以阻止缓存读取,您可能希望创建自己的维护线程,定期调用 Cache.cleanUp()。

如果您想为很少有写入的缓存安排定期缓存维护,只需使用 ScheduledExecutorService 安排维护。

于 2016-12-12T16:55:59.780 回答