一、等待策略相关类:

1、等待策略接口:WaitStrategy接口

该接口只有一个方法,就是返回尝试失败之后,下一次尝试之前的等待时间。
long computeSleepTime(Attempt failedAttempt); 

2、创建等待策略对象的工厂类:com.github.rholder.retry.WaitStrategies类,这是一个常量类,负责创建等待策略对象。

  在该工厂类的内部实现了七种等待策略,如下:

  

二、七种等待策略详解如下:

1、等待固定时间的策略:FixedWaitStrategy类 (默认策略,等待时间为0L)

  这个类很简单,方法抛出异常后,隔固定时间进行一次重试即可。

  // 方法抛出异常后,conputeSleepTime返回固定的时间,单位ms
  @Override
  public long computeSleepTime(Attempt failedAttempt) {
  return sleepTime;
  }

2、等待时间自增的策略:IncrementingWaitStrategy类

  这个类每次重试的间隔时间随着重试次数的增加而增加,每次增加固定的时间。

   // initialSleepTime 默认时间
// increment 自增时间
// getAttemptNumber 第几次重试
    @Override
public long computeSleepTime(Attempt failedAttempt) {
long result = initialSleepTime + (increment * (failedAttempt.getAttemptNumber() - 1));
return result >= 0L ? result : 0L;
}

3、等待时间随机的策略:RandomWaitStrategy类

  这种策略等待时间在某个范围:

    如果传入一个参数,则为 [0L,timeUnit.toMillis(maximumTime)];

    如果传入两个个参数,则为 [minimumTimeUnit.toMillis(minimumTime),maximumTimeUnit.toMillis(maximumTime)]

  

4、等待时间指数形式增长:ExponentialWaitStrategy类

  这中策略等待时间呈指数形式增长,指数形式增长,如果指定最大等待时间,则增长到最大等待时间就不再增长;如果没有指定最大等待时间,则最大等待时间为Long.MAX_VALUE

  主要逻辑如下:

  

5、等待时间以斐波拉契数列形式增长:FibonacciWaitStrategy类

  有三个工厂方法:

    无参:等待时间从 1 增长到 Long.MAX_VALUE

    两个参数:等待时间从 1 增长到 maximumTimeUnit.toMillis(maximumTime),到最大值以后等待时间恒定不变

    三个参数:等待时间从 multiplier 增长到 maximumTimeUnit.toMillis(maximumTime)

  等待时间增长主要实现逻辑:

 

6、如果抛出的是指定异常,则从传入的函数中取得等待时间:ExceptionWaitStrategy类

  如果抛出的是指定异常,则从传入的function中取得等待时间并返回。如果异常不匹配,则返回等待时间为0L。

  具体实现逻辑如下:

    其中lastAttempt.getExceptionCause() 为抛出的异常;exceptionClass为指定异常。

   

  这里简单解释一下 Class.isAssignableFrom(Class clazz) 方法:该方法用来判断一个类Class1和另一个类Class2是否相同或者 Class1是Class2的父类或接口。    

 interface DemoInterface { }

 class DemoParent { }

 public class Demo extends DemoParent implements DemoInterface{

     public static void main(String[] args) {

         System.out.println(Demo.class.isAssignableFrom(DemoParent.class));    // false
System.out.println(Demo.class.isAssignableFrom(DemoInterface.class)); // false System.out.println(DemoParent.class.isAssignableFrom(Demo.class)); // true
System.out.println(DemoInterface.class.isAssignableFrom(Demo.class)); // true System.out.println(Demo.class.isAssignableFrom(Demo.class)); // true
}
}

7、组合多种等待策略,得到等待时间的方式:CompositeWaitStrategy类

  在获取等待时间时会获取多种等待策略各自的等待时间,然后累加这些等待时间并返回。

 /**
* 组合等待策略
* @author yjp
*/
@Test
public void testCompositeWaitStrategy() {
WaitStrategy fibonacciWait = WaitStrategies.fibonacciWait(1000L, 50000L, TimeUnit.MILLISECONDS);
WaitStrategy fixedWait = WaitStrategies.fixedWait(1000L, TimeUnit.MILLISECONDS);
WaitStrategy compositeWait = WaitStrategies.join(fibonacciWait, fixedWait);
assertEquals(2000L, compositeWait.computeSleepTime(failedAttempt(1, 1)));
// 第5次斐波拉契增长的等待时间是 5000L, 加上固定的等待时间 1000L
assertEquals(6000L, compositeWait.computeSleepTime(failedAttempt(5, 1)));
}
  
// --------------源码具体实现----------------
@Override
public long computeSleepTime(Attempt failedAttempt) {
long waitTime = 0L;
for (WaitStrategy waitStrategy : waitStrategies) {
     // 各策略根据各自的逻辑获取自己的等待是时间。然后累加到result中
waitTime += waitStrategy.computeSleepTime(failedAttempt);
}
return waitTime;
}
												

guava-retrying 源码解析(等待策略详解)的更多相关文章

  1. 【源码解析】BlockManager详解

    1 Block管理模块的组件和功能 BlockManager:BlockManager源码解析 Driver和Executor都会创建 Block的put.get和remove等操作的实际执行者 Bl ...

  2. vuex 源码解析(四) mutation 详解

    mutation是更改Vuex的store中的状态的唯一方法,mutation类似于事件注册,每个mutation都可以带两个参数,如下: state ;当前命名空间对应的state payload ...

  3. 我的书籍《深入解析Java编译器:源码剖析与实例详解》就要出版了

    一个十足的技术迷,2013年毕业,做过ERP.游戏.计算广告,在大公司呆过,但终究不满足仅对技术的应用,在2018年末离开了公司,全职写了一本书<深入解析Java编译器:源码剖析与实例详解> ...

  4. nginx源码分析线程池详解

    nginx源码分析线程池详解 一.前言     nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影响.但是经常会有人问道,n ...

  5. 【集合框架】JDK1.8源码分析之ArrayList详解(一)

    [集合框架]JDK1.8源码分析之ArrayList详解(一) 一. 从ArrayList字表面推测 ArrayList类的命名是由Array和List单词组合而成,Array的中文意思是数组,Lis ...

  6. Spring源码之九finishRefresh详解

    Spring源码之九finishRefresh详解 公众号搜索[程序员田同学],专职程序员兼业余写手,生活不止于写代码 Spring IoC 的核心内容要收尾了,本文将对最后一个方法 finishRe ...

  7. 第二章 Google guava cache源码解析1--构建缓存器

    1.guava cache 当下最常用最简单的本地缓存 线程安全的本地缓存 类似于ConcurrentHashMap(或者说成就是一个ConcurrentHashMap,只是在其上多添加了一些功能) ...

  8. Google guava cache源码解析1--构建缓存器(1)

    此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1.guava cache 当下最常用最简单的本地缓存 线程安全的本地缓存 类似于ConcurrentHas ...

  9. Guava Cache源码解析

    概述: 本次主要是分析cache的源码,基本概念官方简介即可. 基本类图: 在官方的文档说明中,Guava Cache实现了三种加载缓存的方式: LoadingCache在构建缓存的时候,使用buil ...

随机推荐

  1. css根据子元素多少类设置子元素的属性--九宫格

    .moment-image-div:nth-child(n+1):nth-last-child(-n+9){ width: 33.33%; float: left; } .moment-image-d ...

  2. Flutter 控件之 Routes 和 Navigator. [PopupRoute]

    一个 App 通常会有多个界面,每个界面实现不同的功能,并在多个界面之间跳转.在 Flutter 中多个界面的跳转是通过 Navigator 来实现的. 在 Flutter 中定义了一个 Overla ...

  3. nginx-编译安装 第一章

    nginx 第一章:编译安装 nginx 官网网站:http://nginx.org/en/ 1.基础说明 基本HTTP服务器功能其他HTTP服务器功能邮件代理服务器功能TCP/UDP代理服务器功能体 ...

  4. 配置firewalld防火墙

    题:请按下列要求在 system1 和 system2 上设定防火墙系统: 允许 group8.example.com 域的客户对 system1 和 system2 进行 ssh 访问. 禁止 my ...

  5. Python 事件驱动了解

    事件驱动 gevent协程可实现自动切换,协程在遇到IO时会进行切换,到另外一个请求,那协程是如何得知在什么时候在切换回去呢?   通常,我们写服务器处理模型的程序时,有以下几种模型: (1)每收到一 ...

  6. Ansible 的初步使用

    在安装好ansible以后,首先使用ansible -h命令和ansible --version 命令查看帮助手册和版本信息. ansible 配置文件 ansible 的配置文件有多个位置,查找顺序 ...

  7. Java调用第三方接口示范

    在项目开发中经常会遇到调用第三方接口的情况,比如说调用第三方的天气预报接口. 使用流程[1]准备工作:在项目的工具包下导入HttpClientUtil这个工具类,或者也可以使用Spring框架的res ...

  8. jquery easyui的应用-1

    下载地址是: www.jeasyui.com/download 当前版本是1.6.7 是由 jquery ui 扩展而来的. 像jquery ui, bootstrap, jquery easyui三 ...

  9. Learning-Python【0】:Windows环境下Python2和Python3的安装

    一.下载 可以在官网下载最新版本, 也可以在以下链接中找想安装的版本下载下来,这里以Python3.6和Python2.7为例 https://www.python.org/ftp/python/ 二 ...

  10. Vmware ESXi 的虚拟机的开机自启动

    ESXi 6.7 以前就注意到虚拟机有个菜单[action->autostart]可以用来自启动(物理机开机之后), 可是设置完之后,总是没成功. 今天重新google了,发觉不但虚拟机,整个物 ...