long startTime = System.nanoTime();
for (int attemptNumber = 1; ; attemptNumber++) {
Attempt<V> attempt;
try {
// 执行成功
V result = attemptTimeLimiter.call(callable);
attempt = new ResultAttempt<V>(result, attemptNumber, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime));
} catch (Throwable t) {
// 执行失败
attempt = new ExceptionAttempt<V>(t, attemptNumber, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime));
}
// 监听器处理
for (RetryListener listener : listeners) {
listener.onRetry(attempt);
}
// 是否符合终止策略
if (!rejectionPredicate.apply(attempt)) {
return attempt.get();
}
// 是否符合停止策略
if (stopStrategy.shouldStop(attempt)) {
throw new RetryException(attemptNumber, attempt);
} else {
// 计算下次重试间隔时间
long sleepTime = waitStrategy.computeSleepTime(attempt);
try {
blockStrategy.block(sleepTime);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RetryException(attemptNumber, attempt);
}
}
}
retryer如何实现重试调用:
1、调用策略
首先调用callable接口,然后同时就把超时时间设置进去,同时调用callable,在callable里面的get方法里面设置time和timeUnit。正常调用返回和失败抛异常的返回都封装在Attempt
2、是否符合终止策略
查看调用结果是不是预设值
3、是否符合停止策略
查看失败重试次数有没有达到预设值
4、计算等待时间,然后休眠
5、继续下一次调用