Java 重复执行任务 - 直到超时或满足条件 - 同步执行

MDD*_*r25 8 java scheduled-tasks

我目前面临一个具体问题,我不知道如何解决。我简单描述一下这个问题:

  • 在一个方法中,我必须调用另一个方法并处理其响应
  • 如果此响应等于某个值,我将继续常规执行
  • 否则,我等待 x 秒(例如 2 秒)并再次调用该方法以再次处理其响应
  • 重复最后一个步骤,直到某个时间段到期或者该方法提供了预期的响应。因此,总的来说,我不会永远等待,而只会等待最多 10 秒,看看该方法是否在那段时间返回预期的响应。
  • 备注:如果该方法不需要 10 秒来传递预期结果,则此后应立即继续常规执行。这意味着如果 2 秒后出现结果,我不想等待 10 秒。

仅使用“老派”意味着我想出了如下的解决方案(部分伪代码以简化)

//No exception handling to simplify method
public ComplexValuePart mainMethod(int id) {
    //Other code executed before

    int maxAmountTries = 5;
    int waitTime = 2000;

    int counter = 0;
    boolean conditionFulfilled = false;
    ComplexValue cv = null;
    while (counter++ < maxAmountTries && !conditionFulfilled) {
        cv = calculatingMethod(id);
        if (cv.conditionHolds()) {
            conditionFulfilled = true;
        } else {
            Thread.sleep(waitTime);
        }
    }

    if (counter == maxAmountTries && !conditionFulfilled) {
        //report error
    }

    //Continue processing with cv
    return doThingsWithCV(cv);
}

public ComplexValue calculatingMethod(int id) {
    //Implementation not relevant here
}
Run Code Online (Sandbox Code Playgroud)

然而,使用Java 8(这是我现在的限制)我认为可能有其他/更好的解决方案?

作为替代方案,我想出了一些使用 ScheduledExecutorService 的方法,例如:

public void mainMethod(int id) {
    //Other code executed before
    ScheduledExecutorService service = Executors.newScheduledThreadPool(1);

    Future<?> future = service.scheduleAtFixedRate(new Runnable() {           
        @Override
        public void run() {
            ComplexValue cv = calculatingMethod(id);
            if (cv.conditionHolds()) {
                //shutdown service including awaitTermination
            }                
        }
    }, 0, 2, TimeUnit.SECONDS);

    try {
        future.get(20, TimeUnit.SECONDS);
    } catch (InterruptedException | ExecutionException | TimeoutException e) {
        //shutdown service including awaitTermination
    }

    //Continue processing with cv - How can I access cv here?
}
Run Code Online (Sandbox Code Playgroud)

为了返回ComplexValue我想我需要使用Callable而不是Runnable?我可以相应地做吗Callable?而且,即使之前服务执行中的条件是OK的,也总是会遇到超时的情况。在这种情况下,我不知道对于实现这样一个非常简单的任务来说,这一切是否有点太多的“开销”。与普通解决方案相比,这种解决方案有什么好处Thread sleep

我是否缺少一些 Java 8 功能来实现这一部分?

注意:我不必在此循环中并行执行不同的任务。在超时到期或出现所需结果之前,主方法的执行不会继续 - 因此,不会async执行。该方法需要根据服务调用的响应返回一些数据。

Moh*_*iya 6

我会使用 TimerTask 来代替。它每隔“waitTime”毫秒重复执行“run”方法。您可以通过调用“timer.cancel()”来指定何时停止重复此任务

public void mainMethod(int id) {
    Timer timer = new Timer();

    timer.schedule(new TimerTask() {
        int counter = 0;
        @Override
        public void run() {
            cv = calculatingMethod(id);
            if (cv.conditionHolds() || counter++ > countLimit) {
                // conditionFulfilled = true;
                timer.cancel();
            }
        }
    }, 0, waitTime);
}
Run Code Online (Sandbox Code Playgroud)