阅读JDK ExecutorCompletionService
文档示例代码
/*
* Suppose instead that you would like to use the first non-null result
* of the set of tasks, ignoring any that encounter exceptions,
* and cancelling all other tasks when the first one is ready:
*
*
* void solve(Executor e,
* Collection<Callable<Result>> solvers)
* throws InterruptedException {
* CompletionService<Result> ecs
* = new ExecutorCompletionService<Result>(e);
* int n = solvers.size();
* List<Future<Result>> futures
* = new ArrayList<Future<Result>>(n);
* Result result = null;
* try {
* for (Callable<Result> s : solvers)
* futures.add(ecs.submit(s));
* for (int i = 0; i < n; ++i) { //??? what's the purpose for this loop?
* try {
* Result r = ecs.take().get();
* if (r != null) {
* result = r;
* break;
* }
* } catch (ExecutionException ignore) {}
* }
* }
* finally {
* for (Future<Result> f : futures)
* f.cancel(true);
* }
*
* if (result != null)
* use(result);
*/
我觉得loop
不是必需的,因为take
会一直阻挡,直到第一个Task
成功,然后直接爆发,我认为i
爆发时总是为零。
这是对的吗?或者我错过了什么?
* for (int i = 0; i < n; ++i) { //??? what's the purpose for this loop?
* try {
* Result r = ecs.take().get();
* if (r != null) {
* result = r;
* break;
* }
* } catch (ExecutionException ignore) {}
* }
答案 0 :(得分:1)
在评论中说
* Suppose instead that you would like to use the first non-null result
* of the set of tasks, ignoring any that encounter exceptions,
* and cancelling all other tasks when the first one is ready:
*
如果第一个结果为null(任务已完成但结果为null)则会尝试获取下一个结果
或
如果当前尝试抛出ExecutionException,则此for循环将跳转到下一个元素并尝试获取下一个结果