java - 异常后自动重试的功能

标签 java android abstract-class

我已经使这个抽象类在抛出某些异常时自动重试网络调用。

  • 我注意不要在 InterruptedException 之后重试 & 未知主机异常
  • 我重试了 5 次。每次失败后 我执行指数回退,从 300 毫秒开始上升到 1500 毫秒。
public abstract class AutoRetry {

  private Object dataToReturn = null;
  public Object getDataToReturn() {
    return this.dataToReturn;
  }

  public AutoRetry() {

    short retry = -1;
    while (retry++ < StaticData.NETWORK_RETRY) {

      try {
        Thread.sleep(retry * StaticData.NETWORK_CALL_WAIT);
        this.dataToReturn = doWork();
        break;
      } catch (InterruptedException | UnknownHostException e) {
        e.printStackTrace();
        this.dataToReturn = null;
        return;
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  protected abstract Object doWork() throws IOException;
}

我使用它如下:

final Object dataAfterWork = new AutoRetry() {     
  @Override
  protected Object doWork() throws IOException {
    return; //a network call which returns something
  }
}.getDataToReturn();

那么这个实现是否良好/正确?


编辑

移至https://codereview.stackexchange.com/questions/87686

最佳答案

这看起来不错,但我会将正在运行的任务与重试分开。也使用泛型,不要只是抛出 Object about。

使用 Java 8 lambda 和方法的 return:

public static <T> Optional<T> doWithRetry(final Supplier<T> t) {
    for (int retry = 0; retry <= StaticData.NETWORK_RETRY; ++retry) {
        try {
            Thread.sleep(retry * StaticData.NETWORK_CALL_WAIT);
            return Optional.of(t.get());
        } catch (InterruptedException | UnknownHostException e) {
            LOGGER.log(Level.SEVERE, "Call failed.", e);
            return Optional.empty();
        } catch (IOException e) {
            LOGGER.log(Level.WARNING, "Call failed. Retry.", e);
        }
    }
    LOGGER.log(Level.SEVERE, "Call failed. Retries exceeded.");
    return Optional.empty();
}

此外,使用真正的记录器,而不是printStackTrace...

用法:

final String data = doWithRetry(() -> {
   //do stuff 
});

如果您的 lambda 需要抛出异常,您需要定义自己的 @FunctionalInterface:

@FunctionalInterface
interface StuffDoer<T> {
    T doStuff() throws Exception;
}

并在方法签名中使用它,您需要处理通用的Exception

Java 8 之前的用法:

final String data = doWithRetry(new StuffDoer<T>() {
    @Override
    public T get() throws Exception {
        return null;
    }
});

关于java - 异常后自动重试的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29799001/

相关文章:

java - 在Java中实例化抽象类

java - 在 DOM4j 文档中搜索元素名称的有效方法

java - Web 应用程序 : DAO and JPA for data layer

java - 如何在不使用 -cp 开关的情况下在 Groovy 中自动加载数据库 jar?

android - layout_height ="0dp"是什么意思?

android - 在 Android 中使用 Facebook Android SDK 将照片上传到 Facebook

php - 我如何使用 json 将数据发布到 php 以根据发布的数据接收数据?

c# - 为什么不能在抽象 C# 类上创建抽象构造函数?

java - 如果客户端继续监听请求,请检查 servlet API?

C++虚函数覆盖