千家信息网

Guava cache如何构建无阻塞缓存

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,本篇内容主要讲解"Guava cache如何构建无阻塞缓存",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Guava cache如何构建无阻塞缓存"吧!Gu
千家信息网最后更新 2026年11月03日Guava cache如何构建无阻塞缓存

本篇内容主要讲解"Guava cache如何构建无阻塞缓存",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Guava cache如何构建无阻塞缓存"吧!

Guava cache 构建无阻塞缓存

适用场景:

guava cache是本地缓存,基于JDK ConcurrentHashMap 实现。不适合分布式环境使用(除非可以保证其节点缓存一致性如: 开源中国社区开源的 J2cache)。如果使用场景简单,没必要使用到缓存复杂特性可以使用ConcurrentHashMap ,比Guava cache 更高效直接。

构建方式:

构建方式有三种:CacheLoader,Callable,Inserted Directly。

CacheLoader:

适用于有一些合理的默认函数来加载或计算与密钥相关的值

Callable:

如果需要覆盖默认值,但仍需要原子"get-if-absent-compute"语义,则应使用get方法传递Callable接口。实现了:如果已缓存,返回;否则创建,缓存和返回。

Inserted Directly:

使用put方式直接插入值。

CacheLoader构建无阻塞缓存:

/** 自定义刷新缓存线程池 */

private static ListeningExecutorService backgroundRefreshPools =

MoreExecutors.listeningDecorator(executorService);

/** 创建缓存 */

public static final LoadingCache cache = CacheBuilder.newBuilder()

.refreshAfterWrite(100,TimeUnit.MILLISECONDS)

.build(new CacheLoader() {

@Override

public String load(String key) {

return getNewValue();

}

@Override

public ListenableFuture reload(String key,String oldValue) {

return backgroundRefreshPools.submit(ReloadCache::getNewValue);

}

});

源码:

public ListenableFuture loadFuture(K key, CacheLoader loader) {

try {

stopwatch.start();

V previousValue = oldValue.get();

// 获取值为空时 加载load方法

if (previousValue == null) {

V newValue = loader.load(key);

return set(newValue) ? futureValue : Futures.immediateFuture(newValue);

}

// 否则执行reload

ListenableFuture newValue = loader.reload(key, previousValue);

if (newValue == null) {

return Futures.immediateFuture(null);

}

return transform(

newValue,

new com.google.common.base.Function() {

@Override

public V apply(V newValue) {

LoadingValueReference.this.set(newValue);

return newValue;

}

},

directExecutor());

} catch (Throwable t) {

ListenableFuture result = setException(t) ? futureValue : fullyFailedFuture(t);

if (t instanceof InterruptedException) {

Thread.currentThread().interrupt();

}

return result;

}

}

reload java doc

当CacheBuilder.refreshAfterWrite(java.time.Duration)或通过调用LoadingCache.refresh(K)刷新现有缓存条目时,将调用此方法。

@GwtIncompatible

public ListenableFuture reload(K key, V oldValue)throws Exception

参数:

key - 应该加载其值的非null键

oldValue - 与key对应的非null旧值

返回值:

不为null的ListenableFuture,不会返回null

异常:

Exception - 如果无法重新加载结果

注意事项:

1、refresh 会"吞掉"缓存更新时的异常操作。依然使用旧值返回。

2、可以使用CacheBuilder.refreshAfterWrite(long,TimeUnit)将自动定时刷新添加到缓存中。

与expireAfterWrite相反,refreshAfterWrite将使键在指定的持续时间后符合刷新条件,但只有在查询条目时才会实际刷新。

(如果将CacheLoader.reload实现为异步,则刷新不会减慢查询速度。)因此,例如,您可以在同一缓存上指定refreshAfterWrite和expireAfterWrite,以便条目上的到期计时器不会每当条目符合刷新条件时,都会盲目重置,因此如果条目在符合刷新条件后未被查询,则允许条目过期。expireAfterWrite 和 refreshAfterWrite 不建议一起使用。

3、refreshAfterWrite 构建缓存更适合应对,热点缓存问题。由于总有旧值返回是一种托底方案。

4、guava cache 刷新功能很多基于其并发工具类Futures提供的线程回调功能。

自定义构建无阻塞缓存:

当没有guava cache 对缓存可使用 ScheduledThreadPoolExecutor + ConcurrentHashMap

注意:对异常的处理,否则导致线程的终止。

参考资料:guava cache wiki https://github.com/google/guava/wiki/CachesExplained

     guava cache api docs https://google.github.io/guava/releases/snapshot-jre/api/docs/

到此,相信大家对"Guava cache如何构建无阻塞缓存"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

缓存 阻塞 条目 查询 方式 方法 条件 线程 内容 功能 场景 实际 学习 复杂 实用 更深 一致 必要 一致性 事项 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技名片 哈尔滨大商圈互联网科技有限公司 互联网科技公司经营范围 互联网科技巨头监管 科技创新与互联网经济 互联网是不是新科技 工业互联网科技新基建 互联网金融 科技 互联网 的科技创新 博兴的互联网电子科技公司 互联网企业和科技型企业 互联网科技创新服务 南平创想时代互联网科技有限公司 伊宁互联网科技做什么的 广东工业互联网大赛深圳学泰科技 上海互联网科技公司ppt 北京互联网科技类企业分布 广州三三互联网科技有限公司 好易买互联网科技 山东亿川互联网科技有限责任公司 新华互联网科技 科技企业和互联网企业 互联网科技卖菜 金融科技创新监管互联网金融 衡水科技产业互联网平台 济南华为互联网科技产业总部基地 乌鲁木齐新华智原互联网科技学校 互联网科技年终奖 工业互联网科技创业 互联网公司属于科技吗
0