Guava缓存器源码分析——数据加载

     Guava缓存器加载数据的方式有两种:同步(loadSync)与异步(loadAsync)。

     同步方式——
     只在取数据 V get(K, int, CacheLoader)执行过程中会被调用到。
     同步加载数据代码如下:
          ListenableFuture<V> loadingFuture = loadingValueReference.loadFuture(key, loader);
          return getAndRecordStats(key, hash, loadingValueReference, loadingFuture);

     异步方式——
     只在刷新数据refresh(K, int, CacheLoader, boolean)执行过程中会被调用到。
     guava缓存器没有提供类似refreshAll()的方法来刷新所有值,而只是提供了 refresh(Key)的方法来刷新某个键值对,这里的刷新动作是异步执行的,如果有人在值被彻底刷新之前,取这个Key的值,返回的还是刷新前的值。

     在执行refresh时,会调用loadAsync方法来异步加载数据,同时通过isDone()方法来判断任务是否完成,正常结束、异常或者是被取消,这个方法都会返回true。
      ListenableFuture<V> result = loadAsync(key, hash, loadingValueReference, loader);
           if (result.isDone()) {
             try {
               return Uninterruptibles.getUninterruptibly(result);
             } catch (Throwable t) {
        }
      }
      return null;

     不管是同步或异步方式,都会调用到loadFuture(key, loader)方法,先将数据取到。
     loadFuture执行流程:
     1、取key对应的旧值;
     2、旧值不存在,则调用load方法取新值。
     3、通过futureValue的set方法来设置新值,成功则返回futureValue,否则返回Futures.immediateFuture(newValue)。
     4、旧值存在,则调用reload方法重取新值。
     5、reload方法返回类型为ListenableFuture<V>,结果不为null则直接返回,否则返回 Futures.<V>immediateFuture(null)。
     Futures的immediateFuture方法,返回了一个ImmediateSuccessfulFuture对象,在其构造函数中初始化值,该Future不能被取消或超时,它的isDone()方法只返回true。
    

     异步方式,在取数完成后,将注册一个监听器,完成数据的最终加载并统计信息。
     loadingFuture.addListener(
          new Runnable() {
            @Override
            public void run() {
              try {
                    V newValue = getAndRecordStats(key, hash, loadingValueReference, loadingFuture);
                    loadingValueReference.set(newValue);
              } catch (Throwable t) {
                    logger.log(Level.WARNING, "Exception thrown during refresh", t);
                    loadingValueReference.setException(t);
              }
            }
          }, sameThreadExecutor);

     涉及的类:
这部分代码,通过Runnable接口实现,没有返回结果。   
其中SettableFuture通过set(Object)或setException(Throwable)来设置值。
       AbstractFuture类通过AbstractQueuedSynchronizer来处理同步问题和保证线程安全。所有涉及状态改变的方法,都会返回一个boolean值来表明状态改变是否成功,有效的状态有running, completed, failed, cancelled。这个类通过ExecutionList来保证当Future结束时所有注册的监听器,或完成后添加的监听器都能被执行。Runnable-Executor对存放在execution列表中,但不一定按它们添加的顺序执行,如果一个监听器在Future结束后添加,它将被立即执行,就算在它之前的监听器还没执行。
      如果需要知道返回结果,可以使用Guava提供的ListenableFutureTask类,该类继承至FutureTask并实现了ListenableFuture接口, 可自由选择实现Runnable的void run()方法,或Callable的 V call()方法(有返回结果),这几个类看的不够仔细,需要再研究。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值