在有些需要快速响应的场景下,可以使用并发框架,实现异步重试。
比如使用线程池ThreadPoolExecutor,把请求接口转化成一个异步任务,将任务放入线程池中异步执行,并发地重试请求接口。可以在任务执行完成后,判断任务执行结果,如果失败则继续重试。
public class CallbackRetry {
private static final Object lock = new Object();
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(
10, // 核心线程数
10, // 最大线程数
0L, // 空闲线程存活时间
TimeUnit.MILLISECONDS, // 时间单位
new LinkedBlockingQueue<>() // 任务队列
);
public RetryResult doRetry() throws ExecutionException, InterruptedException {
//最大重试次数
int maxRetryCount = 3;
int currentRetryCount = 0;
//创建异步任务,用于执行重试方法
Callable task = () -> {
RetryResult retryResult = new RetryResult();
//......重试方法
return retryResult;
};
Future<RetryResult> future = null;
while(currentRetryCount < maxRetryCount) {
try{
//为了避免并发请求下的请求重复和顺序问题,使用锁来解决并发问题
synchronized (lock) {
future = executor.submit(task);
}
RetryResult result = future.get();
//判断任务执行结果
if(result.isSuccess()) {
break;
}
} catch (Exception e) {
currentRetryCount++;
// 处理异常
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
return future.get();
}
class RetryResult<T>{
//是否重试成功
private boolean success;
//重试结果
private T obj;
public RetryResult(){}
public RetryResult(boolean success, T obj) {
this.success = success;
this.obj = obj;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
}