我有一组线程,所有线程都需要并行执行,我必须等待所有这些线程完成。
我应该使用普通的Thread
还是ExecutorService
?对于ExecutorService.awaitTermination
我必须给予一定的时间,我愿意等待,但Thread.join
我绝对不能。
我没有对线程给出的结果做任何事情,我不需要任何futures
。
编辑:
ExecutorService es = Executors.newFixedThreadPool(kThreads);
List<Callable<Void>> calls = new LinkedList<>();
container.forEach(
calls.add(() -> { //creating a thread/task
BufferedImage scaledBufferedImage=imageService.scale(...);
imageService.transferToAWS(...);
return null;
})
);
es.invokeAll(calls); //executes each task
es.shutdown(); //ensure that no new tasks will be accepted
es.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); //wait for all tasks to finish
return kLinksToTheScaledImages;
答案 0 :(得分:1)
寻求执行者服务。这为管理线程终止提供了许多其他好处(例如,容量扩展和执行逻辑与实际任务的分离)
答案 1 :(得分:1)
使用执行程序,您只需执行此操作。
ex.shutdown();
while (!ex.awaitTermination(1, TimeUnit.MINUTES)) {
}
其中ex是您的 ExecutorService 。在循环中,您可以检查您的线程是否仍然存在或类似的东西。
答案 2 :(得分:1)
正如您所说,您并非需要 Future
这样,但您可以使用它们来等待终止。
由于您使用的是Java 8,因此可以通过
执行此操作ExecutorService es = Executors.newFixedThreadPool(kThreads);
container.stream()
.map(d -> createRunnable(d)) // now you have Runnables
.map(es::submit) // now they're Futures
.forEach(Future::get); // get() will wait for futures to finish
编辑: 我刚刚意识到流可能会阻止并行性开始,所以你需要在中间收集它们:
List<Future<?>> futures = container.stream()
.map(d -> createRunnable(d)) // now you have Runnables
.map(es::submit) // now they're Futures
.collect(Collectors.toList());
futures.forEach(Future::get);
实际上,我完全理解人们对于在没有期货返回价值的情况下等待而感到困惑。 IMO,让每个未来都返回它创建的上传链接会更有意义:
String scaleAndUpload() {
BufferedImage scaledBufferedImage=imageService.scale(...);
imageService.transferToAWS(...);
return linkToUploadedImage;
}
所以你会得到像
这样的东西List<Future<?>> futures = container.stream()
.map(d -> scaleAndUpload()) // now you have Runnables
.map(es::submit) // now they're Futures
.collect(Collectors.toList());
return futures.stream()
.map(Future::get) // collect the link when the future is finished
.collect(Collectors.toList()); // create a list of them
答案 3 :(得分:1)
我应该使用普通的旧线程还是ExecutorService?
对于ExecutorService.awaitTermination我必须给出一定的时间,我愿意等待,但对于Thread.join我绝对不能。
您必须查看此帖子才能正确关闭ExecutorService
。
How to properly shutdown java ExecutorService
这篇文章中引用了更多的替代品:
答案 4 :(得分:0)
你可以while(!executor.isTerminated) {}
。那么你不必说你愿意等多久。