目录
- RetryUtils方法
- main方法测试
- 拓展-函数接口
RetryUtils方法
该Java函数retryOnException用于在指定重试次数内执行某个操作,并在遇到异常时重试。功能如下:
- 对传入的操作(retryCallable)进行尝试执行。
- 如果执行成功且结果符合预期(matching方法返回true),则停止重试并返回结果。
- 否则,在达到最大重试次数前,等待一段时间后再次尝试,并记录日志信息。
- 最终返回最后一次的结果,无论是否成功。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** * <p>异常重试工具 </p>** @author Javen*/
public class RetryUtils {private static final Logger log = LoggerFactory.getLogger(RetryUtils.class);/*** 回调结果检查*/public interface ResultCheck {/*** 是否匹配** @return 匹配结果*/boolean matching();/*** 获取 JSON** @return json*/String getJson();}/*** 在遇到异常时尝试重试** @param retryLimit 重试次数* @param retryCallable 重试回调* @param <V> 泛型* @return V 结果*/public static <V extends ResultCheck> V retryOnException(int retryLimit,java.util.concurrent.Callable<V> retryCallable) {V v = null;for (int i = 0; i < retryLimit; i++) {try {v = retryCallable.call();} catch (Exception e) {log.warn("retry on " + (i + 1) + " times v = " + (v == null ? null : v.getJson()), e);}if (null != v && v.matching()) break;log.error("retry on " + (i + 1) + " times but not matching v = " + (v == null ? null : v.getJson()));}return v;}/*** 在遇到异常时尝试重试** @param retryLimit 重试次数* @param sleepMillis 每次重试之后休眠的时间* @param retryCallable 重试回调* @param <V> 泛型* @return V 结果* @throws java.lang.InterruptedException 线程异常*/public static <V extends ResultCheck> V retryOnException(int retryLimit, long sleepMillis,java.util.concurrent.Callable<V> retryCallable) throws java.lang.InterruptedException {V v = null;for (int i = 0; i < retryLimit; i++) {try {v = retryCallable.call();} catch (Exception e) {log.warn("retry on " + (i + 1) + " times v = " + (v == null ? null : v.getJson()), e);}if (null != v && v.matching()) {break;}log.error("retry on " + (i + 1) + " times but not matching v = " + (v == null ? null : v.getJson()));if (sleepMillis > 0) {Thread.sleep(sleepMillis);}}return v;}
}
main方法测试
public static void main(String[] args) {RetryUtils.ResultCheck resultCheck = RetryUtils.retryOnException(100, () -> new RetryUtils.ResultCheck() {int randomInt = RandomUtil.randomInt(1, 100);@Overridepublic boolean matching() {System.out.println("randomInt:" + randomInt);return randomInt < 5;}@Overridepublic String getJson() {return String.valueOf(randomInt);}});String json = resultCheck.getJson();System.out.println(json);}
拓展-函数接口
- 方法
public static <V> V retryOnException(java.util.concurrent.Callable<V> retryCallable) {V v;try {v = retryCallable.call();} catch (Exception e) {throw new RuntimeException(e);}return v;}
- 调用
Integer integer = retryOnException(() -> {return RandomUtil.randomInt(1, 100) < 50 ? 2: 1;});System.out.println(integer);