前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊jetcache的ProxyCache

聊聊jetcache的ProxyCache

作者头像
code4it
发布2024-06-19 20:20:38
580
发布2024-06-19 20:20:38
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究一下jetcache的ProxyCache

ProxyCache

jetcache-core/src/main/java/com/alicp/jetcache/ProxyCache.java

ProxyCache继承了Cache接口,它定义了getTargetCache方法,并默认实现了unwrap方法

SimpleProxyCache

jetcache-core/src/main/java/com/alicp/jetcache/SimpleProxyCache.java

SimpleProxyCache实现了ProxyCache接口,它定义了cache属性,其方法均委托给了cache对象

LoadingCache

jetcache-core/src/main/java/com/alicp/jetcache/LoadingCache.java

LoadingCache继承了SimpleProxyCache,其get方法会判断config.getLoader()是否为null,不为null则执行AbstractCache.computeIfAbsentImpl(key, loader,config.isCacheNullValue() ,0, null, this);getAll方法多了loader以及config.isCachePenetrationProtect()的处理逻辑,对于开启cachePenetrationProtect的会通过CacheUtil.createProxyLoader包装一下loader,然后AbstractCache.synchronizedLoad去加载value

createProxyLoader

jetcache-core/src/main/java/com/alicp/jetcache/CacheUtil.java

CacheUtil提供了两个createProxyLoader,一个loader类型为CacheLoader,一个为Function;其load及loadAll方法委托给了loader,主要是增加了耗时统计并创建CacheLoadEvent,交给eventConsumer.accept(event)去消费

synchronizedLoad

jetcache-core/src/main/java/com/alicp/jetcache/AbstractCache.java

AbstractCache提供了synchronizedLoad静态方法,它先通过buildLoaderLockKey来创建lockKey,之后while循环,computeIfAbsent指定lockKey的LoaderLock,对于loaderThread为当前线程的先通过GET获取result,若为success则返回,否则通过loader加载,然后通知cacheUpdater,最后执行ll.signal.countDown(),对于非当前thread的则根据指定的timeout执行ll.signal.await(),若await超时或者InterruptedException则执行newLoader.apply,否则对于success的直接返回value,非success则继续循环处理

RefreshCache

jetcache-core/src/main/java/com/alicp/jetcache/RefreshCache.java

RefreshCache继承了LoadingCache,它定义了taskMap用于存储RefreshTask,它覆盖了computeIfAbsent方法,复用了AbstractCache定义的静态方法computeIfAbsentImpl,传入的cache为this;其get及getAll方法对于config.getRefreshPolicy()及config.getLoader()不为null的会额外执行addOrUpdateRefreshTask

addOrUpdateRefreshTask

addOrUpdateRefreshTask方法先获取refreshMillis,对于refreshMillis小于等于0的不处理,大于0的先通过getTaskId(key)获取taskId,然后通过taskMap.computeIfAbsent获取或者创建refreshTask,最后更新refreshTask的lastAccessTime;当新创建refreshTask时,会通过JJetCacheExecutor.heavyIOExecutor().scheduleWithFixedDelay(task, refreshMillis, refreshMillis, TimeUnit.MILLISECONDS)去调度该refreshTask,即每隔refreshMillis调度执行refreshTask

RefreshTask

RefreshTask的run方法先判断stopRefreshAfterLastAccessMillis,若stopRefreshAfterLastAccessMillis大于0且lastAccessTime + stopRefreshAfterLastAccessMillis小于now则执行cancel,然后返回;之后通过concreteCache获取具体的cache,对于AbstractExternalCache类型的执行externalLoad,否则执行load load方法通过loader去加载,对于needUpdate的执行PUT去更新;对于externalLoad的会先获取refreshTimeResult,对于CacheResultCode.NOT_EXISTS的则shouldLoad为true,对于refreshTimeResult.isSuccess()的对于currentTime大于等于Long.parseLong(refreshTimeResult.getValue().toString()) + refreshMillis的则shouldLoad为true,对于非shouldLoad的且是multiLevelCache则执行refreshUpperCaches然后返回;否则使用concreteCache.tryLockAndRun去加锁然后执行load方法,若加锁不成功且是multiLevelCache的,则通过JetCacheExecutor.heavyIOExecutor().schedule去调度执行refreshUpperCaches

SimpleCacheManager.create

jetcache-core/src/main/java/com/alicp/jetcache/SimpleCacheManager.java

SimpleCacheManager的create方法对于config.getRefreshPolicy()不为null的则创建RefreshCache去包装cache,否则再对于config.getLoader()不为null使用LoadingCache去包装cache

小结

ProxyCache继承了Cache接口,它定义了getTargetCache方法,并默认实现了unwrap方法;SimpleProxyCache实现了ProxyCache接口,它定义了cache属性,其方法均委托给了cache对象

LoadingCache继承了SimpleProxyCache,其get方法会判断config.getLoader()是否为null,不为null则执行AbstractCache.computeIfAbsentImpl(key, loader,config.isCacheNullValue() ,0, null, this);getAll方法多了loader以及config.isCachePenetrationProtect()的处理逻辑,对于开启cachePenetrationProtect的会通过CacheUtil.createProxyLoader包装一下loader,然后AbstractCache.synchronizedLoad去加载value RefreshCache继承了LoadingCache,它定义了taskMap用于存储RefreshTask,它覆盖了computeIfAbsent方法,复用了AbstractCache定义的静态方法computeIfAbsentImpl,传入的cache为this;其get及getAll方法对于config.getRefreshPolicy()及config.getLoader()不为null的会额外执行addOrUpdateRefreshTask SimpleCacheManager的create方法根据QuickConfig先构造local或者remote或者multiLevelCache,再根据config的loader或者refreshPolicy去创建包装类,对于config.getRefreshPolicy()不为null的则创建RefreshCache去包装cache,否则再对于config.getLoader()不为null使用LoadingCache去包装cache

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

本文分享自 码匠的流水账 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ProxyCache
  • SimpleProxyCache
    • LoadingCache
      • createProxyLoader
      • synchronizedLoad
    • RefreshCache
      • addOrUpdateRefreshTask
      • RefreshTask
  • SimpleCacheManager.create
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档