等待来自不同执行者的任务

时间:2013-11-29 09:11:04

标签: java multithreading concurrency

我将某些逻辑操作分成不同的任务,并在不同的java.util.concurrent.Executors上并发运行。

对于操作中的所有任务,我希望在每个任务完成后得到通知(即,在这种情况下完成所有操作后通知是不够的。)

是否有java.util.concurrent.CompletionService的实现,它可以等待并提供来自多个Executor的任务结果?这甚至可能吗?

我当前(不完美)的解决方案是按照提交顺序从CompletionService获取的任务队列。使用监听器的专有解决方案也是可能的,但如果可能的话我宁愿使用java.util.concurrent。

编辑:我最终按照Greg的建议做了,除了我扩展FutureTask而不是Runnable。

1 个答案:

答案 0 :(得分:2)

您可能只需使用知道CompletionService队列的实体包装您的Executors。

public class MyCompletionService implements Executor /* optional implements CompletionService too */ {
      private final Executor mExecutor;
      private Queue<Runnable> mRunnableQueue;

      public MyNotifyingExecutorWrapper (Queue<Runnable> queueToNotify, Executor wrapped) {
             mExecutor = wrapped;
             mRunnableQueue = queueToNotify;
      }


      public execute(Runnable command) {
             mExecutor.execute(new NotifyingRunnable(command, mRunnableQueue));
      }

      private static class NotifyingRunnable implements Runnable {
            private final Queue<Runnable> mRunnables;
            private Runnable mRunnable;

            public NotifyingRunnable(Runnable runnable, Queue<Runnable> done) {
                 mRunnables = done;
                 mRunnable = runnable;
            }
            public void run() {
                  mRunnable.run();
                  mRunnables.add(mRunnable);
            }
      }
  }

您可以使此类实现CompletionExecutorService并选择一个实例来进行/轮询(假设您的所有实例都使用相同的队列),或者只是以更原始的意义创建队列的使用者。

   public static void main(String[] args) {
         LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue();
         private MyCompletionService[] executors = ... {} ;

         while(true){
            System.out.println(String.format("%s: Woohoo %s is done!", System.currentTimeMillis(), queue.take()));
         }
   }

}

注意省略了异常处理和执行单个任务的实际隐式代码:)