假设我有一个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 setinvalidate
应该立即删除条目-不等待其他查询-并应强制在下一个查询中将该值重新加载到该键。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/