前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >guava cache 源码分析

guava cache 源码分析

作者头像
用户3147702
发布2022-06-27 16:53:15
6070
发布2022-06-27 16:53:15
举报
文章被收录于专栏:小脑斧科技博客

1. 背景

上一篇文章中,我们详细介绍了 guava cache 的使用方法,尤其是在其中重点介绍了 guava cache 异步回种的用法,那么,性能优异的异步回种缓存究竟是如何实现的呢?本文我们就来详细阅读 guava cache 的完整流程代码,抽丝剥茧,学习其中的思想与智慧。

guava cache 用法详解

2. 基本思想

guava cache 异步回种基本思想:

cache.get() 完整流程图:

3. 加锁同步调用 lockedGetOrLoad

如图所示,下述场景下,缓存直接通过加锁同步调用的方式获取数据:

  1. 缓存为空;
  2. 缓存中获取数据为空;
  3. 缓存中数据已超过 expireTime 并且状态不是 loading 状态。

guava cache 在上述情况下调用 lockedGetOrLoad() 方法获取数据,这个方法中,通过加 AQS 锁避免多个线程同时 load 获取数据,然后通过回调 load() 方法同步获取数据。

4. 异步 refresh

如果第一步操作中,缓存中数据获取正常,没有超过 expireTime,那么就需要判断是否过了 refreshTime 了。

expireTime 与 refreshTime 的区别如下:

  1. 数据一旦超过 expireTime,则说明数据不可用,已经是失效数据。
  2. 数据如果没有超过 expireTime,但超过了 refreshTime,说明数据虽然没有失效,但是需要尝试从数据源获取并刷新数据。

如图所示,scheduleRefresh() 方法的流程并不复杂:

  1. 判断是否已经超过 refreshTime,如果已经超过,则执行 refresh 方法尝试获取新数据;
  2. 新数据获取成功,则返回新数据,否则返回 oldValue。

5. 异步加载数据 loadAsync

上述流程中,refresh() 方法具体执行的流程就是 loadAsync() 方法,如图所示:

loadAsync 方法分两种情况:

  1. 同步 load:当旧值不存在时,执行同步 load 方法获取数据,保证数据返回;
  2. 异步 reload:当旧值存在时,执行异步 reload 方法获取数据,保证耗时可控。

无论是通过同步 load 方法还是异步 reload 方法获取数据,都会最终封装成 Future 对象,并且为这个 Future 对象添加 Listener,从而能够在数据获取完成后,设置缓存及更新缓存中数据的状态。

6. 总结

了解了 guava cache 异步回种的基本思想,也许你会觉得这一套解决方案的实现是如此简单,那么,我们知道,memcache、redis 都是只有提供了同步接口的,那么,你是否可以在此基础上实现一套异步回种方案呢?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小脑斧科技博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 背景
  • 2. 基本思想
  • 3. 加锁同步调用 lockedGetOrLoad
  • 4. 异步 refresh
  • 5. 异步加载数据 loadAsync
  • 6. 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档