java.util.concurrent.Callable接口可以实现多线程,同时还能实现一个简易重试机制。
查看Callable接口源码可知,它内部的call()方法带返回值,同时抛出了异常。
public interface Callable {
V call() throws Exception;
}
那么咱们可以根据返回值的存在情况,来作为重试的依据:如果返回值存在,证明重试操作完成;如果返回值不存在,继续进行重试。
/**
*
*
* @Title: retry
* @Description: 重试方法
* @param @param count 重试次数
* @param @param callAble 重试回调
* @param @param interval 时间间隔 单位:ms
* @param @return 设定文件
* @return T 返回类型
* @throws
*/
public static T retry(int count,Callable callAble,Long interval){
T t=null;
for (int i = 0; i < count; i++) {
try {
System.out.println("retry on: "+i);
t=callAble.call();
System.out.println("Callable call :"+t.toString());
} catch (Exception e) {
//发生异常证明一次重试失败
System.err.println("retry error: "+e.getMessage());
}
if(t!=null) break;
//重试时间间隔,不为空/不为0
if(interval!=null && interval.longValue()!=0){
try {
Thread.sleep(interval.longValue());
} catch (InterruptedException e) {
System.err.println("InterruptedException: "+e.getMessage());
}
}
}
return t;
}
我在重试方法中添加的重试次数和间隔时间的控制,基本可以满足重试机制的要求了。
测试下:
1、代码抛出异常,无法返回数据,一直进行重试操作
public class Main {
public static void main(String[] args) throws Exception {
Callable callAble=new Callable(){
@Override
public String call() throws Exception {
System.out.println("----------call");
System.out.println("当前线程名——" + Thread.currentThread().getName());
throw new RuntimeException();
//return "3";
}
};
RetryUtil.retry(3, callAble,2000l);
}
}
运行结果:
retry on: 0
----------call
当前线程名——main
retry error: null
retry on: 1
----------call
当前线程名——main
retry error: null
retry on: 2
----------call
retry error: null
当前线程名——main
2、代码正常运行,并能正常返回数据,重试一次便结束
public static void main(String[] args) throws Exception {
Callable callAble=new Callable(){
@Override
public String call() throws Exception {
System.out.println("----------call");
System.out.println("当前线程名——" + Thread.currentThread().getName());
//throw new RuntimeException();
return "3";
}
};
RetryUtil.retry(3, callAble,2000l);
}
运行结果:
retry on: 0
----------call
当前线程名——main
Callable call :3
通过测试可以看出,代码基本满足了重试机制的要求。