假设我有一个Cache,其定义如下:

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

从我阅读的中读取(如果我输入错了,请纠正我):

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

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

最佳答案

来自该链接的第一部分:How does Guava expire entries in its CacheBuilder?

我将重点介绍 expireAfterAccess ,但是expireAfterWrite的过程几乎相同。从机制上讲,当您在CacheBuilder中指定 expireAfterAccess 时,缓存的每个段都会维护一个链表访问队列,以便按从最近访问到最近访问的顺序对条目进行维护。高速缓存条目实际上本身就是链接列表中的节点,因此,在访问条目时,它会将自己从访问队列中的旧位置删除,然后将其移动到队列的末尾。

第二部分:
从此链接:Guava CacheLoader - invalidate does not immediately invalidate entry if both expireAfterWrite and expireAfterAccess are set
invalidate应该立即删除条目-不等待其他查询-并应强制在下一个查询中将该值重新加载到该键。
cleanUp:执行缓存所需的所有暂挂维护操作。确切地执行哪些 Activity (如果有)取决于实现。

来自 Guava 文档: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安排维护。

关于谷歌 Guava 缓存invalidateAll()和cleanUp()之间的区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41105447/

10-11 02:32
查看更多