我有一个“Runnable”线程正在启动一些“Callable”线程,我想在所有上述线程完成其工作时显示结果。
最好的方法是什么?
我的代码如下
Connector.java(启动Runnable线程)
public class Connector {
private static void anyFileConnector() {
// Starting searching Thread
ExecutorService executor = Executors.newFixedThreadPool(100);
executor.submit(traverse, executor);
//HERE I WANT MY ALL SEARCH RESULTS/OUTPUT : CURRENTLY IT IS STARTING OTHER THREADS AND NOT SHOWING ME ANY RESULTS BECAUSE NONE OF THEM WAS FINISHED.(IN CONSOLE, I WAS ABLE TO SEE RESULTS FROM ALL THE THREADS
setSearchResult(traverse.getResult());
executor.shutdown();
}
}
Traverse.java(Runnable Thread) 我正在使用ExecutorCompletionService来处理它......但它并没有产生任何区别。 :(
public class Traverse implements Runnable {
public void run() {
ExecutorService executor = Executors.newFixedThreadPool(100);
ExecutorCompletionService<List<ResultBean>> taskCompletionService =
new ExecutorCompletionService<List<ResultBean>>(executor);
try (DirectoryStream<Path> stream = Files
.newDirectoryStream(dir)) {
Search newSearch = new Search();
taskCompletionService.submit(newSearch);
}
list.addAll(taskCompletionService.take().get());
}
}
Search.java(可调用线程)
public class Search implements Callable<List<ResultBean>> {
public List<ResultBean> call() {
synchronized (Search.class) {
// It will return results
return this.search();
}
}
}
答案 0 :(得分:2)
转到CyclicBarrier
,您就可以实现这一目标。
一旦所有线程完成其工作,循环屏障将执行任务,这是您可以打印结果的地方。
检查CyclicBarrier
:http://javarevisited.blogspot.com/2012/07/cyclicbarrier-example-java-5-concurrency-tutorial.html
答案 1 :(得分:1)
简单 - 所有Callables都将返回Future对象,您可以通过以阻塞等待方式调用Future.get()来等待并获取结果。所以你的问题只是一个for循环,等待阻塞的callables的每个未来。
之后,只需汇总结果以返回客户端。
答案 2 :(得分:1)
执行程序服务的submit方法可以返回Future
个对象的列表。你能为你的情况做些什么是在while循环中调用这些Future对象的isDone()
方法。
每当任何未来任务完成时,此方法将返回true。您现在可以在此处调用get()
方法来获取此任务返回的值。通过这种方式,您可以获得所有未来任务值,而无需等待任何特定任务完成(因为您的第一个未来任务可能具有最长的完成时间)