ExecutorService 等待所有 Future 完成
ExecutorService wait for all Future to complete
我有以下 ExecutorService 代码。
try{
ExecutorService executor = Executors.newFixedThreadPool(5);
List<Callable<String>> taskList = new ArrayList<Callable<String>>(5);
for(int i=1;i<=5;i++){
taskList.add(new SimpleTask());
}
List<Future<String>> list = executor.invokeAll(taskList);
executor.shutdown();
System.out.println(list.get(0).get());
System.out.println("Exit");
}catch(Exception e){
e.printStackTrace();
}
class SimpleTask implements Callable<String> {
@Override
public String call() throws Exception {
return new Date().toString();
}
}
我想知道list.get(0).get()
会等待所有任务完成吗?
不,代码不会等待每个任务完成。通过调用 list.get(0).get()
,您将检索第一个可选调用 get()
,它将根据 documentation 阻塞线程。
要等待每个可调用完成,您需要遍历列表并查看是否全部完成。当然,您可以通过对它们中的每一个调用 get()
来做到这一点,但是您会一直阻塞主线程。我自己更喜欢在等待其他线程执行时能够做一些事情。
使用 Java 8 个流的示例:
// filter if any future is not done yet
while ( list.stream().anyMatch(i->!i.isDone()) )
{
// Do whatever you want parallel to the evaluation of the Future objects
// example
System.err.println( "Not all are done yet." );
}
// process your results
// example:
String[] results = list.stream().map( Main::evalGet ).toArray(String[]::new);
注意:priavte static <T> TevalGet(Future<T> fu)
只是一个包装函数,用于保持 lambda 表达式干净的异常处理,看起来类似于:
private static <T> T evalGet( Future<T> fu )
{
T obj = null;
try
{
obj = fu.get();
}
catch ( InterruptedException | ExecutionException e )
{
e.printStackTrace();
}
return obj;
}
这里的代码不会在执行 list.get(0).get()
语句时等待,而是 executor.invokeAll(taskList)
语句,因为 invokeAll()
方法本身会等待所有线程的复杂化。
了解更多
我有以下 ExecutorService 代码。
try{
ExecutorService executor = Executors.newFixedThreadPool(5);
List<Callable<String>> taskList = new ArrayList<Callable<String>>(5);
for(int i=1;i<=5;i++){
taskList.add(new SimpleTask());
}
List<Future<String>> list = executor.invokeAll(taskList);
executor.shutdown();
System.out.println(list.get(0).get());
System.out.println("Exit");
}catch(Exception e){
e.printStackTrace();
}
class SimpleTask implements Callable<String> {
@Override
public String call() throws Exception {
return new Date().toString();
}
}
我想知道list.get(0).get()
会等待所有任务完成吗?
不,代码不会等待每个任务完成。通过调用 list.get(0).get()
,您将检索第一个可选调用 get()
,它将根据 documentation 阻塞线程。
要等待每个可调用完成,您需要遍历列表并查看是否全部完成。当然,您可以通过对它们中的每一个调用 get()
来做到这一点,但是您会一直阻塞主线程。我自己更喜欢在等待其他线程执行时能够做一些事情。
使用 Java 8 个流的示例:
// filter if any future is not done yet
while ( list.stream().anyMatch(i->!i.isDone()) )
{
// Do whatever you want parallel to the evaluation of the Future objects
// example
System.err.println( "Not all are done yet." );
}
// process your results
// example:
String[] results = list.stream().map( Main::evalGet ).toArray(String[]::new);
注意:priavte static <T> TevalGet(Future<T> fu)
只是一个包装函数,用于保持 lambda 表达式干净的异常处理,看起来类似于:
private static <T> T evalGet( Future<T> fu )
{
T obj = null;
try
{
obj = fu.get();
}
catch ( InterruptedException | ExecutionException e )
{
e.printStackTrace();
}
return obj;
}
这里的代码不会在执行 list.get(0).get()
语句时等待,而是 executor.invokeAll(taskList)
语句,因为 invokeAll()
方法本身会等待所有线程的复杂化。
了解更多