java - 有没有办法将 ScheduledExecutorService 与 ExecutorCompletionService 一起使用?

标签 java multithreading completion-service

我正在尝试同时使用 ExecutorCompletionService 和 ScheduledExecutorService。

我需要做的是安排不同的 Activity ,每个 Activity 都有“执行前的延迟”,然后根据上次运行的结果“重新安排它们”(不同的延迟)。”

我遇到的问题是我不能使用带有“延迟”的 ExcecutorCompletionService 提交

我尝试了以下方法,但它会永远阻塞...

显然,我遗漏了 Java 语言中的一个基本问题。

有没有办法将任务安排到 ScheduledExecutorService,以便 CompletionService“知道”?

public class Bar {

    private ScheduledExecutorService scheduledExecutor;
    private Future<Status> action1Future;
    private Future<Status> action2Future;
    private ExecutorCompletionService<Status> pool;
    private long delay1 = 10;
    private long delay2 = 20;
    private long delay3 = 30;

    public void start() {
        scheduledExecutor = Executors.newScheduledThreadPool(3);

        Action1 a1 = new ActionOne(); // Action1 implements Callable<Status>
        Action2 a2 = new ActionTwo(); // Action2 implements Callable<Status>

        pool = new ExecutorCompletionService<Status>(scheduledExecutor);
        action1Future = scheduledExecutor.schedule(a1, delay1, TimeUnit.SECONDS);
        action2Future = scheduledExecutor.schedule(a2, delay1, TimeUnit.SECONDS);
        monitorAndRestart();
    }

    private void monitorAndRestart() {
         boolean isDone=false;
        do {
        try {
            // THIS IS WHERE IT BLOCKS.
            Future<Status> processedItem = pool.get();
            if (processedItem == action1Future) {
                if (processedItem.get() == Status.GOOD) {
                    action1Future = scheduledExecutor.schedule(new ActionOne(), delay1, TimeUnit.SECONDS);
                } else {
                    action1Future = scheduledExecutor.schedule(new ActionOne(), delay2, TimeUnit.SECONDS);
                }
            } else if (processedItem == action2Future) {
                if (processedItem.get() == Status.GOOD) {
                    action1Future = scheduledExecutor.schedule(new ActionOne(), delay2, TimeUnit.SECONDS);
                } else {
                    action1Future = scheduledExecutor.schedule(new ActionOne(), delay3, TimeUnit.SECONDS);
                }
            }
        } catch (InterruptedException e) {
            isDone = true;
            // handle this.. shudown whatever
        }
        catch (ExecutionException e) {
            // handle this
        }
      } while (isDone == false);
    }

    public static void main(String[] args) {
        Bar myRunner = new Bar();
        myRunner.start();
    }
}

如果我把“delay in the Callable”通过 new ActionOne(delay) 创建可调用对象;并使用 CompletionService.submit(..) 它有效。

actionFuture1 = pool.submit(new ActionOne(delay1));
/////


public class ActionOne implements Callable<Status>(
   private final delay;
   public ActionOne(long dl) {
       delay=dl;
   }
   Status call() {
       try {
         Thread.sleep(delay * 1000); // seconds
          return doSomething()
       } catch (...) { //thread.sleep execptions}
   }
 }

所以我想最后一个问题如下:ScheduledExecutorService 是否有比 Thread.sleep(delay) 方法更根本的东西?

最佳答案

我们在我们的一个应用程序中进行了这种重新安排,我们决定像 Ed Thomas 建议的那样包装任务。 (我们还通过传递一个返回任务下一次执行时间的迭代器,使重新调度变得非常灵活 - 允许我们使用许多不同的调度策略)。

另一种选择是继承 ScheduledThreadPoolExecutor 并覆盖 afterExecute。这最终可能比包装任务更干净。

关于java - 有没有办法将 ScheduledExecutorService 与 ExecutorCompletionService 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23796960/

相关文章:

java - 为什么在 Annotation 接口(interface)中声明 Object 的非最终公共(public)方法?

java - 如何在Java Spring Boot应用程序中从mysql动态生成Enum类型?

c - Pthread 屏障和树莓派

java - 什么时候应该使用 CompletionService 而不是 ExecutorService?

java - 在Java中无法识别多个生产者/消费者何时完成

java - FixedThreadPool 和 ExecutorCompletionService 的 OutOfMemory 错误

java - 为什么我不能在 Java 中使用\u000D 和\u000A 作为 CR 和 LF?

java - 如何在 libgdx 中定义可突出显示、可点击的自定义对象(风险游戏)

objective-c - 用户多次生成同一个 Action 等待下载怎么办?

java - Android:线程没有更新值