expireAfterAccess、expireAfterWrite、expireAfter
// 基于固定的过期时间驱逐策略
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.expireAfterAccess(5, TimeUnit.MINUTES)
.build(key -> createExpensiveGraph(key));
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(key -> createExpensiveGraph(key));
// 基于不同的过期驱逐策略
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.expireAfter(new Expiry<Key, Graph>() {
public long expireAfterCreate(Key key, Graph graph, long currentTime) {
// Use wall clock time, rather than nanotime, if from an external resource
long seconds = graph.creationDate().plusHours(5)
.minus(System.currentTimeMillis(), MILLIS)
.toEpochSecond();
return TimeUnit.SECONDS.toNanos(seconds);
}
public long expireAfterUpdate(Key key, Graph graph,
long currentTime, long currentDuration) {
return currentDuration;
}
public long expireAfterRead(Key key, Graph graph,
long currentTime, long currentDuration) {
return currentDuration;
}
})
.build(key -> createExpensiveGraph(key));
expireAfterAccess 表示上次读写超过一定时间后过期,expireAfterWrite 表示上次创建或更新超过一定时间后过期。expireAfter 允许复杂的表达式,过期时间可以通过 entry 等外部参数确定。
修改缓存配置
// 在代码里面动态的指定最大Size
cache.policy().eviction().ifPresent(eviction -> {
eviction.setMaximum(4 * eviction.getMaximum());
});
分析缓存内数据
cache.policy().eviction().ifPresent(eviction -> {
// 获取热点数据Map
Map<String, Object> hottestMap = eviction.hottest(10);
// 获取冷数据Map
Map<String, Object> coldestMap = eviction.coldest(10);
System.out.println("热点数据:" + JSON.toJSON(hottestMap).toString());
System.out.println("冷数据:" + JSON.toJSON(coldestMap).toString());
});
手动异步加载
AsyncCache<Key, Graph> cache = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.maximumSize(10_000)
.buildAsync();
// 查找一个缓存元素, 没有查找到的时候返回null
CompletableFuture<Graph> graph = cache.getIfPresent(key);
// 查找缓存元素,如果不存在,则异步生成
graph = cache.get(key, k -> createExpensiveGraph(key));
// 添加或者更新一个缓存元素
cache.put(key, graph);
// 移除一个缓存元素
cache.synchronous().invalidate(key);
一个AsyncCache
是 Cache
的一个变体,AsyncCache
提供了在 Executor上生成缓存元素并返回 CompletableFuture的能力。这给出了在当前流行的响应式编程模型中利用缓存的能力。
synchronous()
方法给 Cache
提供了阻塞直到异步缓存生成完毕的能力。
当然,也可以使用 AsyncCache.asMap()
所暴露出来的ConcurrentMap的方法对缓存进行操作。
默认的线程池实现是 ForkJoinPool.commonPool() ,当然你也可以通过覆盖并实现 Caffeine.executor(Executor)
方法来自定义你的线程池选择。