Guava缓存是轻量级的,它将内容缓存到运行内存中。如果系统中某些值(比如一些配置表)被频繁查询使用,并且我们愿意消耗一些内存空间来提升应用的速度,减轻数据库压力的话,Guava缓存将会是一个不错的选择。由于缓存是存储在运行内存中的,所以我们需要确保缓存的大小不超出内存的容量。
创建缓存
我们可以直接创建Guava缓存对象,而不使用任何的CacheLoader:
1 | Cache<String, String> cache = CacheBuilder.newBuilder().build(); |
key值是大小写敏感的,所以使用cache.getIfPresent("HELLO")
将返回null值。
接下来看看如何使用CacheLoader创建缓存对象:
1 | CacheLoader<String, String> loader = new CacheLoader<String, String>() { |
方法getUnchecked
作用为:当值不存在时,会通过CacheLoader计算出值,然后存到缓存中。
驱逐机制
我们可以定义一些驱逐缓存的机制来限制缓存的大小。
限制缓存数目
我们可以通过maximumSize
来限制缓存的条目:
1 | Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(3).build(); |
我们限制最多只能存储3个值,所以k4的存入把最早的k1给驱逐出去了,类似于FIFO。
限制缓存大小
我们可以自定义权重函数来限制缓存的大小:
1 | Weigher<String, String> weigher = (key, value) -> value.length(); |
上面例子中,我们通过maximumWeight(15)
指定了缓存的最大容量,权重规则为value的长度。k3,k4和k5的value长度加起来为13,所以k1和k2的值存不下了,被驱逐。
设置缓存时间
我们可以设置缓存的有效时间和缓存的活跃时间。
设置缓存的活跃时间为2s:
1 | Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterAccess(2, TimeUnit.SECONDS).build(); |
上面代码中,我们通过cache.getIfPresent("k1")
获取了k1的值,然后让线程阻塞1秒,这时候k1和k2的有效时间大约为1秒左右。接着又获取了k1的值,所以k1的有效时间还是2秒,k2为1秒,再次让线程阻塞1秒后,k1的有效时间为1秒,k2已经失效了。打印输出的结果和我们预期的一致。
设置缓存的有效时间为2s:
1 | Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterWrite(2, TimeUnit.SECONDS).build(); |
因为我们设置缓存有效时间为2秒,所以2秒后所有缓存都过期失效了,无论期间获取过多少次缓存。
weakKeys&softValues
默认情况下,Guava缓存键值都有强引用,我们可以使用weakKeys和softValues来让键值变为弱引用,这样垃圾收集器在必要的情况下将会工作:
1 | Cache<String, String> cache = CacheBuilder.newBuilder().weakKeys().softValues().build(); |
刷新缓存
可以通过refreshAfterWrite
设置缓存自动刷新间隔,或者可以直接调用refresh
方法来手动刷新缓存:
1 | Cache<String, String> cache = CacheBuilder.newBuilder().refreshAfterWrite(1,TimeUnit.SECONDS).build(); |
添加多个缓存
可以通过putAll
来一次性添加多个缓存:
1 | Cache<String, String> cache = CacheBuilder.newBuilder().build(); |
删除缓存
Cache.invalidate(key)
方法通过key来删除缓存:
1 | Cache<String, String> cache = CacheBuilder.newBuilder().build(); |
除此之外,我们也可以通过Cache.invalidateAll(keys)
一次性删除多个缓存或者Cache.invalidateAll()
删除全部缓存。
我们还可以给删除事件添加监听器:
1 | RemovalListener<String, String> listener |
增删改查
简单封装一个Guava缓存工具类:
1 | public class GuavaCacheUtil { |