
guava cache的过期淘汰并非实时自动进行,而是通过在写入操作期间或偶尔的读取操作中触发维护任务来清理过期条目。这种设计避免了创建专用线程的开销和锁竞争,同时确保了在受限环境中的可用性,从而优化了性能和资源利用。
许多开发者在使用Guava Cache时,可能会误以为一旦设置了过期时间(TTL),缓存中的条目就会在精确的到期时刻被立即移除。然而,Guava Cache的过期淘汰机制并非如此。它采用了一种“按需清理”的策略,而不是依赖一个独立的后台线程进行持续的维护。
何时触发清理?
Guava Cache的清理操作主要在以下两种情况下触发:
这种设计意味着,一个条目即使已经过期,也可能不会立即从缓存中消失。它会一直存在,直到下一次维护操作被触发时才会被移除。当尝试获取一个已过期但尚未被清理的条目时,Guava Cache会识别其过期状态并返回null(或重新加载,如果配置了CacheLoader),同时将其标记为待清理。
为何采用这种机制?
Guava Cache选择这种“懒惰”的清理方式,是基于性能和资源利用的考量:
Guava Cache提供了两种主要的过期策略,可以通过CacheBuilder进行配置:
基于写入时间的过期(expireAfterWrite): 从条目被写入缓存(或最后一次更新)的时间点开始计算,经过指定时间后过期。
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.TimeUnit;
public class GuavaCacheExample {
public static void main(String[] args) throws InterruptedException {
Cache<String, String> cache = CacheBuilder.newBuilder()
.expireAfterWrite(10, TimeUnit.SECONDS) // 写入后10秒过期
.maximumSize(100) // 最大缓存容量
.build();
cache.put("key1", "value1");
System.out.println("放入 key1: " + cache.getIfPresent("key1")); // value1
Thread.sleep(5000); // 等待5秒
System.out.println("5秒后获取 key1: " + cache.getIfPresent("key1")); // value1
Thread.sleep(6000); // 再等待6秒,总计11秒
// 此时key1已过期,但可能尚未被清理
System.out.println("11秒后获取 key1: " + cache.getIfPresent("key1")); // null (已过期,即使未被物理移除)
cache.put("key2", "value2"); // 写入操作,可能触发清理
System.out.println("写入key2后再次尝试获取 key1: " + cache.getIfPresent("key1")); // null
}
}基于访问时间的过期(expireAfterAccess): 从条目被读取或写入缓存的时间点开始计算,经过指定时间后过期。每次访问都会重置计时器。
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.TimeUnit;
public class GuavaCacheAccessExpiryExample {
public static void main(String[] args) throws InterruptedException {
Cache<String, String> cache = CacheBuilder.newBuilder()
.expireAfterAccess(5, TimeUnit.SECONDS) // 5秒内未访问则过期
.build();
cache.put("data", "important_data");
System.out.println("Initial data: " + cache.getIfPresent("data")); // important_data
Thread.sleep(3000); // 等待3秒
System.out.println("Accessed data after 3s: " + cache.getIfPresent("data")); // important_data (访问重置计时器)
Thread.sleep(3000); // 再等待3秒 (总计6秒,但上次访问在3秒前)
System.out.println("Accessed data after another 3s: " + cache.getIfPresent("data")); // important_data (上次访问后3秒,未过期)
Thread.sleep(6000); // 再等待6秒 (上次访问后9秒,已过期)
System.out.println("Accessed data after another 6s: " + cache.getIfPresent("data")); // null
}
}Guava Cache的过期淘汰机制是一个经过精心设计的权衡,旨在提供高性能和高可用性,同时避免不必要的资源消耗。它通过在写入或读取操作中“搭便车”的方式进行清理,而不是依赖一个独立的后台线程。理解这一机制对于正确配置和使用Guava Cache至关重要,能够帮助开发者避免潜在的误解,并更好地优化应用程序的性能。
以上就是深入理解Guava Cache的过期淘汰机制的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号