ScheduledExecutorService 如果有异常则异步运行任务直到成功

问题描述 投票:0回答:1

我正在尝试使用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();
                }
            }
        }
    });
}
java asynchronous
1个回答
0
投票

您的方法看起来不错,您可能需要考虑一些改进和注意事项:

  1. 我没有注意到你在哪里递增计数器,所以我没有使用

    counter.get() < MAX_RETRY
    ,而是采用了
    counter.getAndIncrement() <= MAX_RETRY
    。这将是该方法的第一次调用 + 3 次重试调用。

  2. 可能值得考虑一个可以重试的特定异常,但如果您确实需要它来处理任何异常,那么您可以在 catch 块中留下一个通用的

    Exception

  3. 最好在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();
            }
        }
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.