Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 等待来自不同执行者的任务_Java_Multithreading_Concurrency - Fatal编程技术网

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

Java 等待来自不同执行者的任务,java,multithreading,concurrency,Java,Multithreading,Concurrency,我将某些逻辑操作分为不同的任务,在不同的java.util.concurrent.Executors上并发运行 对于操作中的所有任务,我希望在每个任务完成后收到通知(即,在这种情况下,在所有任务完成后发出通知是不够的) 是否有java.util.concurrent.CompletionService的实现,它可以等待并提供来自多个执行者的任务结果?这可能吗 我目前(不是完美的)解决方案是按照提交顺序从CompletionService获取任务队列。使用监听器的专有解决方案也是可能的,不过如果可

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

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

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

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


编辑:我最终按照格雷格的建议做了,只是扩展了FutureTask而不是Runnable

您可能只需要用一个知道CompletionService队列的实体包装您的执行者

i、 e

公共类MyCompletionService实现Executor/*可选也实现CompletionService*/{
私人最终执行人执行人;
专用队列mrunablequeue;
公共MyNotifyingExecutorWrapper(队列通知,执行器已包装){
mExecutor=包裹;
mrunablequeue=queueToNotify;
}
公共执行(可运行命令){
execute(newnotifyingrunnable(命令,mrunablequeue));
}
私有静态类NotifyingRunnable实现Runnable{
私有最终队列名称;
私人可运行的mRunnable;
public NotifyingRunnable(Runnable,Runnable,Queue done){
mRunnables=完成;
mRunnable=runnable;
}
公开募捐{
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()));
         }
   }
publicstaticvoidmain(字符串[]args){
LinkedBlockingQueue=新建LinkedBlockingQueue();
私有MyCompletionService[]执行者=…{};
while(true){
System.out.println(String.format(“%s:Woohoo%s完成!”),System.currentTimeMillis(),queue.take());
}
}
}


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

CountDownLatch+FutureTask的集合take()将其从队列中移除后,有什么保证可以执行Runnable?执行线程将执行Runnable.run(),完成后,它只会将已完成的runnable添加到已完成任务的队列中。不确定您在寻找什么样的保证,因为所有可运行程序都可以再次执行(从api级别)。我建议针对您尝试建模的情况使用阻塞队列。这样,当某件事情完成时,take()调用将取消阻止。您当然是对的。但是,此解决方案对于处理可调用和可运行文件并不理想。我更愿意找到一个用期货来管理它的解决方案。也许那时可以用期货来代替返回的Runnables。但是,您无法知道哪个Runnable/Callable产生了哪个未来。
   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()));
         }
   }