在程序开发过程中常遇因外部资源…问题,造成当前线程执行失败的场景,常用解决方案是重试,如下是个人为此场景设计的可重试方案。
/**
* 可重试服务
* <pre>调用案例:{@code
* RetryAbleService retryService = new RetryAbleService() {
* @Override
* public boolean process() {
* boolean retryAble = false;
* //调用业务处理......
* return retryAble;
* }
* @Override
* public void retryFailed() {
* //多次重试之后,最终失败的回调处理......
* }
* };
* }</pre>
* boolean retryResult = retryService.retry(3, 500);
*
* @author <a href="mailto:tansheng526@163.com">tansheng</a>
* @version $$Id$$
* @since 1.0
*/
public interface RetryAbleService {
/**
* 重试
*
* @param retryMaxQty 重试次数
* @param waitMillis 等待时间
*/
public default boolean retry(final int retryMaxQty, final long waitMillis) {
boolean returnFlag = true;
boolean retryFlag = true;
int doneTimes = 0;
while (retryFlag) {
try {
retryFlag = !process();
} catch (UnsupportException ex) {
throw new UnsupportException(ex.getMessage());
} catch (Throwable ex) {
ex.printStackTrace();
retryFlag = true;
}finally {
doneTimes++;
}
if (retryFlag && retryMaxQty > 0 && doneTimes > retryMaxQty) {
retryFlag = false;//超过最大重试次数,不进行重试
returnFlag = false;
try {
retryFailed();
} catch (Exception ex) {
ex.printStackTrace();
}
break;
}
if (retryFlag) {
try {
Thread.sleep(waitMillis);
} catch (InterruptedException ex) {}
}
}
return returnFlag;
}
/**
* 重试失败的最终处理方式
*/
public abstract void retryFailed();
/**
* 处理业务
*
* @return true: 处理成功; false 处理失败,等待重试
*/
public abstract boolean process();
}