1、缓存(Guava Cache等)使用场景
(1)目标数据经常重复被访问
(2)目标数据计算代价比较高
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumSize(100) // 最大容量,逼近阈值则启动回收
.expireAfterWrite(60, TimeUnit.SECONDS) // 定时回收,缓存项在给定时间内没有被写访问,创建或覆盖则回收
.expireAfterAccess(30, TimeUnit.SECONDS) // 定时回收,缓存项在给定时间内没有被读/写访问,则回收
.build(
new CacheLoader<Key, Graph>() {
// 加载逻辑
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
// 刷新缓存,注意是异步刷新,因此放到线程池里面执行
// 在刷新操作进行时,缓存仍然可以向其他线程返回旧值
public ListenableFuture<Key, Graph> reload(final Key key, Graph prevGraph) {
return threadPool.submit {
return load(key);
}
}
});
// 查询缓存
LoadingCache查询的正规方式是使用get(K)方法。这个方法要么返回已经缓存的值,要么使用CacheLoader向缓存原子地加载新值
(1)目标数据经常重复被访问
(2)目标数据计算代价比较高
(3)目标数据对实时性要求不高
(1)Guava Cache通常被设定为自动回收元素,ConcurrentMap只有显式删除,否则永久占用内存
【获取缓存】-【如果没有】-【则计算】
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumSize(100) // 最大容量,逼近阈值则启动回收
.expireAfterWrite(60, TimeUnit.SECONDS) // 定时回收,缓存项在给定时间内没有被写访问,创建或覆盖则回收
.expireAfterAccess(30, TimeUnit.SECONDS) // 定时回收,缓存项在给定时间内没有被读/写访问,则回收
.build(
new CacheLoader<Key, Graph>() {
// 加载逻辑
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
// 刷新缓存,注意是异步刷新,因此放到线程池里面执行
// 在刷新操作进行时,缓存仍然可以向其他线程返回旧值
public ListenableFuture<Key, Graph> reload(final Key key, Graph prevGraph) {
return threadPool.submit {
return load(key);
}
}
});
// 查询缓存
LoadingCache查询的正规方式是使用get(K)方法。这个方法要么返回已经缓存的值,要么使用CacheLoader向缓存原子地加载新值
510

被折叠的 条评论
为什么被折叠?



