Guava Cache expireAfterWrite 与 refreshAfterWrite区别

Guava Cache提供expireAfterWrite和refreshAfterWrite功能,前者在写入后一段时间失效,通过get触发统一失效;后者在写入后一段时间异步刷新,旧值在刷新期间仍可使用。自动刷新由线程池完成,无需额外编写刷新代码。测试显示在高并发场景下,Guava Cache能正确处理刷新与访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面的文章缓存篇(一)- Guava有讲到Guava Cache有区别于ConcurrentHashMap的使用,就是因为其自带有自动刷新和自动失效的功能,避免我们去自己编写刷新和失效的后台线程程序。Guava Cache提供了简单便捷的api给我们使用,但是研究源码发现这里的自动刷新缓存和自动失效原理,并非是Guava Cache帮我们去添加了类似后台线程自动刷新或失效逻辑的代码,而是用另外一种巧妙的方式进行。

expireAfterWrite 与 refreshAfterWrite区别

expireAfterWrite

在缓存更新后某个时间失效缓存,这里Guava内部会对某个时间点失效的缓存做统一失效,只要有get访问任一key,就会失效当前时间失效的缓存,会移除当前key。所以这里也希望我们创建的缓存数据量不宜过大,使用guavaCache最好是设置一下maximumSize,避免出现内存溢出的情况。失效后需要获取新值才可会返回。

refreshAfterWrite

是指在创建缓存后,如果经过一定时间没有更新或覆盖,则会在下一次获取该值的时候,会在后台异步去刷新缓存,如果新的缓存值还没有load到时,则会先返回旧值。这里跟上面的expireAfterWrite不同的是,及时到了该刷新的时间,不会失效旧值和移除对应key。在后台异步刷新的过程中,如果当前是刷新状态,及时有其他线程访问到旧值,依然只有一个线程在更新,不会出现多个线程同时刷新同一个key的缓存。

是否需要编写缓存刷新代码

不需要。上面讲到,使用了refreshAfterWrite后台会异步去刷新。这里后台刷新是使用线程池去完成异步刷新过程,即ListeningExecutorService sameThreadExecutor = MoreExecutors.sameThreadExecutor();

测试代码

这里是模拟1000个线程在3秒内10次从guavaCacha拿数据,通过loadTimes判断刷新了多少次,输出结果可以看到拿到的结果正确性。

代码已上传至https://github.com/zhuzhenke/common-caches

public class GuavaCacheRefreshTest {
   
    @Data
    public class SkuCache {
   
        private String skuId;
        private String skuCode;
        private Long realQuantity;
    }

    AtomicInteger loadTimes = new AtomicInteger(0);
    AtomicInteger count = new AtomicInteger
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值