此链接的第一部分: 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 安排维护。