1 简介
GuavaCache为我们提供了一个本地缓存,他类似于ConcurrentMap。两者最大的区别在于Map中的元素在显示地清除之前会一直保存,而GuavaCache能够限制缓存中元素的数量并设置过期时间。通常来说,GuavaCache适用于以下情况:
- 愿意消耗一些内存空间来提升速度
- 预料到某些键会被查询一次以上
- 缓存中存放的数据总量不会超出内存容量 而事实上,GuavaCache的设计灵感也来源于ConcurrentHashMap,使用多个segments方式的细粒度锁,在保证线程安全的同时,支持高并发场景需求,同时支持多种类型的缓存清理策略,包括基于容量的清理、基于时间的清理、基于引用的清理等。
2 本地缓存 vs 分布式缓存
本地缓存(Local Cache):针对后端应用服务器,本地缓存又叫JVM缓存
-
优点:其最大的优点是应用和缓存是在同一个进程内部,请求缓存非常快速,没有过多的网络开销
-
缺点:容量有限,不能存放过多的内容;每个jvm实例都会存一份,存在数据冗余
分布式缓存(Remote Cache):与应用分离的缓存组件或服务,如redis
-
优点:存储容量大,跟机器有关不受应用影响、缓存全局共享
-
缺点:存在网络开销,相对于本地缓存存取速度较慢
3 快速入门
3.1 引入依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.0-jre</version>
</dependency>
3.2 加载
首先,我们需要构建Cache对象。在GuavaCache中我们可以定义默认的加载规则,也就是说当我们查找一个不存在的key时GuavaCache会按照加载规则帮我们计算出对应的value存入缓存中。
CacheLoader
创建CacheLoader,只需要实现load方法,如下面代码示例。当我们调用get方法获取指定key的缓存值时,如果key的value值还没有缓存,Guava Cache则会自动调用load方法加载value值到缓存并返回。
LoadingCache<String, Object> loadingCache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(3, TimeUnit.SECONDS)
.build(
new CacheLoader<String, Object>() {
@Override
public Object load(String s) throws Exception {
return s + "-" + s;
}
}
);
try {
String key = "Hello";
String result = (String) loadingCache.get(key);
System.out.println(result);
} catch (Exception e) {
}
运行结果:
Hello-Hello
Callable
当然,我们也可为特定的key制定专门的规则。不论我们有没有提供CacheBuilder
LoadingCache<String, Object> loadingCache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(3, TimeUnit.SECONDS)
.build(
new CacheLoader<String, Object>() {
@Override
public Object load(String s) throws Exception {
return s + "-" + s;
}
}
);
try {
String key = "Hello";
String result = (String) loadingCache.get(key, new Callable<String>() {
@Override
public String call() throws Exception {
return key + "+" + key;
}
});
System.out.println(result);
} catch (Exception e) {
}
运行结果:
Hello+Hello
3.3 其他接口
直接看中文教程吧,写的比较详细了:wizardforcel.gitbooks.io/guava-tutor…
4 参考
Guava Cache使用介绍:juejin.cn/post/684490…