在Java中重试延迟的最佳方法

时间:2016-10-06 00:27:06

标签: java

在我的程序中,我调用一个可以返回值或“”的方法,基本上我希望它在每次尝试之间以1秒的延迟重试查找值3次,直到它获得值或尝试已经完成了。

这就是我目前所拥有的,但我觉得这个解决方案非常糟糕,特别是不得不把try / catch放在睡眠中。有没有人知道更好的方法来延迟重试?

File's Owner

5 个答案:

答案 0 :(得分:2)

Fixed Poll Interval

awaitility功能可能有所帮助:

Awaitility.with()
  .pollInterval(1, SECONDS)
  .atMost(3, SECONDS)
  .await()
  .until(() -> ("" != getValue(input)));

它提供了一个流畅的界面来同步异步操作。

答案 1 :(得分:1)

我认为使用try .. catch没有任何问题。

这与异常不是错误的基本理念是一致的 - 它只是一种情况发生,一种处理控制流的方式。

所以 - 我喜欢你的解决方案。我不会改变它。

答案 2 :(得分:1)

在一天结束时,你无法解决需要捕捉异常的事实

你可以做的就是隐藏它通过你自己的方法

public static void mySleep (int val) {
    try { 
        TimeUnit.SECONDS.sleep(val);
    } catch (InterruptedException e) {
        log.error("Thread interrupted");
    }
}

所以你main功能变得更清晰了

while (value.equals("") && tries < 3){
    mySleep (1);
    value = getValue(input);
    tries += 1;
}

答案 3 :(得分:0)

您的示例有效,基本上任何解决方案都将以通用形式位于其中心。如果您不喜欢编写自己的重试的详细程度,请查看FailsafeGuava-Retrying,它们是完成相同基本操作的库。

答案 4 :(得分:0)

这是Thread.sleep和捕获中断异常的示例。主要问题是它将阻塞线程直到完成。为避免这种情况,您需要一些应用服务器级别的支持以使其undertow for example

    private void sendWithRetry(final InternetAddress[] toAddresses, final Transport transport, final MimeMessage msg) throws MessagingException {

        boolean guard = false;
        for (int retry = 0; !guard && retry < SMTP_RETRY_LIMIT - 1; ++retry) {
            try (final Transport trans = transport) {
                trans.connect();

                // Actually send the message
                trans.sendMessage(msg, toAddresses);

                // Close the connection
                guard = true;
            } catch (final MessagingException me) {
                log.warn("Retry {}", retry, me);
                try {
                    Thread.sleep(SMTP_RETRY_DELAY_IN_MS);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    log.warn("Interrupt exception received so interrupting thread and breaking out of retry loop");
                    guard = true;
                }
            }
        }
        if (!guard) {
            try (final Transport trans = transport) {
                trans.connect();

                // Actually send the message
                trans.sendMessage(msg, toAddresses);
            }
        }
    }