我正在尝试使用ScheduledExecutorService在java中实现重试机制,在失败的情况下在30秒后异步重试函数,并且最多重试3次。我还没有使用过 ScheduledExecutorService,所以如果有更好的方法来编写它,我真的很想获得一些输入。我的目标是如果有任何异常则重试并执行函数 runMyChoreTillItSucceeds 直到成功。
public void retryIfAnyExceptionTillItSucceeds(PaymentDO pmDO, TransactionDO txnDO) {
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
AtomicInteger counter = new AtomicInteger(1);
final int MAX_RETRY = 3;
scheduler.execute(new Runnable() {
@Override
public void run () {
try {
runMyChoreTillItSucceeds(pmDO, txnDO);
scheduler.shutdown();
}
catch (Exception e) {
if (counter.get() < MAX_RETRY) {
scheduler.schedule(this, 30, TimeUnit.SECONDS);
}
else {
scheduler.shutdown();
}
}
}
});
}
您的方法看起来不错,您可能需要考虑一些改进和注意事项:
我没有注意到你在哪里递增计数器,所以我没有使用
counter.get() < MAX_RETRY
,而是采用了counter.getAndIncrement() <= MAX_RETRY
。这将是该方法的第一次调用 + 3 次重试调用。
可能值得考虑一个可以重试的特定异常,但如果您确实需要它来处理任何异常,那么您可以在 catch 块中留下一个通用的
Exception
最好在catch块中使用
scheduler.shutdownNow()
而不是scheduler.shutdown()
来立即中断线程。这可确保取消任何待处理的任务。
public static void retryIfAnyExceptionTillItSucceeds(PaymentDO pmDO, TransactionDO txnDO) {
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
AtomicInteger counter = new AtomicInteger(1);
final int MAX_RETRY = 3;
scheduler.execute(new Runnable() {
@Override
public void run() {
try {
runMyChoreTillItSucceeds(pmDO, txnDO);
scheduler.shutdownNow(); // Shutdownnow immediately on success
} catch (SpecificRuntimeException e) { // catch specific exception to retry
if (counter.getAndIncrement() <= MAX_RETRY) {
scheduler.schedule(this, 2, TimeUnit.SECONDS);
} else {
scheduler.shutdownNow(); // Shutdown if max retries reached
}
} catch (Exception e) {
// Handle other exceptions if needed
scheduler.shutdownNow();
}
}
});
}