我读了post关于executorService
我希望在订购时填写固定大小的结果集合。
当我知道任务i
应将结果存储在array[i]
时,我可以填充数组。
是否有另一种内置方式按照提交任务的顺序存储结果?我可以填写列表而不是数组吗?
答案 0 :(得分:3)
只需将Future
返回的submit()
存储在数组或列表中,然后遍历此列表并在每个未来调用get()
:
List<Callable<Result>> tasks = ...;
List<Future<Result>> futures = new ArrayList<>();
for (Callable<Result> task : tasks) {
futures.add(executor.submit(task));
}
List<Result> results = new ArrayList<>();
for (Future<Result> future : futures) {
results.add(future.get());
}
答案 1 :(得分:3)
您可以使用Executors.invokeAll()
方法。来自javadocs:
参数:
任务 - 任务集合
返回:
表示任务的Futures列表,其顺序与给定任务列表的迭代器生成的顺序相同,每个已完成。
ExecutorService executor = Executors.newFixedThreadPool(SOME_SIZE);
Collection<Callable<T>> tasks = ...; // fill collection with callable tasks
List<Future<T>> futures = executor.invokeAll(tasks);
invokeAll()
在所有提交的任务完成执行后返回。
然后迭代返回的期货并在每个期货上调用get()
:
List<T> results =
futures.stream().map(Future::get).collect(Collectors.toList());
结果顺序将与tasks
集合中的那个匹配。
单行:
List<T> results =
executor.invokeAll(tasks).stream().map(Future::get).collect(Collectors.toList());
答案 2 :(得分:0)
将Future
个对象的结果按照创建顺序添加到列表中:
// given some tasks and an executor
List<Callable<MyResult>> tasks;
ExecutorService exec;
List<MyResult> results = exec.invokeAll(tasks).stream()
.map(Future::get).collect(Collectors.toList());