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

标签 java scheduled-tasks

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

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

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

//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
}

但是,使用 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?
}

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

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

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

最佳答案

我会改用 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);
}

关于Java 重复执行任务 - 直到超时或条件满足 - 同步执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54588572/

相关文章:

java - SLF4J 和 Logback 的依赖管理

android - 我想在android中的不同日期(星期一,星期二等)的特定时间安排任务

asp.net-mvc - 安排每周执行一次的 Quartz.NET 触发器

TFS2013 计划生成 : Manually triggered Builds are not being accounted for when Scheduled Build are kicked off

java - Spring Controller 内的多线程 "No thread-bound request found"

java - 如果我的目录名包含空格,Hibernate 无法加载 JAR 文件!

c# - 我如何安排 C# Windows 服务每天执行任务?

node.js - 使用 Cassandra 在 Node.js 中的多数据中心环境中分发计划任务

java - 如何通过 aws Java SDK 公开 S3 对象?

java - 使用 twitter4j 从特定位置提取主题标签的推文