【问题标题】:Execute Runnable, Timeout, then Retry执行 Runnable,超时,然后重试
【发布时间】:2013-11-05 22:56:41
【问题描述】:

我正在使用 Ebay API 对商品出价。如果出现某种网络错误导致 API 调用不返回,我想在之后立即重试调用。看起来很简单,但我整天都在兜圈子。我对线程没有真正的经验。这是它应该如何工作还是我完全错了?

这是 Callable 类:

public class PlaceOfferThread implements Callable<Boolean> {

    private PlaceOfferCall call;
    public Boolean isComplete;

    public PlaceOfferThread (PlaceOfferCall p) {
        call = p;
    }

    @Override
    public Boolean call() throws Exception {

        try {
            call.placeOffer(); 
            return true;
        }
        catch (InterruptedException ex) {
        ex.printStackTrace();
        }
        return false;
    }
}

这里是调用者

    int timeout = 10;
    int maxRetries = 5;
    int retries = 0;

    ExecutorService executor = Executors.newSingleThreadExecutor();
    PlaceOfferThread thread = new PlaceOfferThread(call);

    boolean flag = false;

    while (!flag && retries++ < maxRetries) {

        Future<Boolean> future = null;

        try {
            future = executor.submit(thread);
            flag = future.get(timeout, TimeUnit.SECONDS);
            future.cancel(true);
        }
        catch(TimeoutException ex) {

            // no response from Ebay, potential network issues
            // resubmit the call to Ebay with the same invocation id

            future.cancel(true);

         }
         catch (Exception threadException) {

            // any other exception indicates that we got a response from Ebay
            // it just wasn't the response we wanted

            throw new Exception(threadException.getMessage());
        }
    }

    executor.shutdown(); // TODO

【问题讨论】:

  • 你不告诉我们你的代码是怎么不工作的吗?会发生什么?

标签: java multithreading timeout


【解决方案1】:

如果出现某种网络错误导致 API 调用没有返回,我想在之后立即重试调用。

我不能 100% 确定您的应用程序现在是如何工作的,但这里有一些想法:

  1. 当您调用future.cancel(true) 时,您很可能不会停止当前事务。除非您使用 NIO 调用,否则 IO 方法是不可中断的。中断线程只是在线程上设置一个标志,并导致那些抛出InterruptedException(如sleepwaitjoin)的方法这样做。您必须查看 Thread.currentThread().isInterrupted() 方法才能看到中断。

  2. 我认为正确的做法是设置底层 http-client 对象的连接和 IO 超时,如果出现问题,让它抛出或退出并报错。试图从另一个线程中杀死它会更加困难。

  3. 在查看您的代码时,我不确定您为什么要使用线程。也许您正在进行其他处理,但直接拨打电话可能会更好。然后您可以调整HttpClient 的IO 超时并适当地处理它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    相关资源
    最近更新 更多