这听起来像是一个用例ExecutorCompletionService
// wrap tasks A, B and C into runnables (or callables if you need some result):
Callable<Result> taskA = ...;
Callable<Result> taskB = ...;
Callable<Result> taskC = ...;
// create an ExecutorCompletionService
// to which you must pass an ExecutorService
// (choose one according to your precise use case)
// (the newCachedThreadPoolExecutor might not be a sensible choice)
ExecutorCompletionService e = new ExecutorCompletionService(Executors.newCachedThreadPoolExecutor());
Set<Future<Result>> futures = new HashSet<>();
// submit your tasks:
futures.add(e.submit(taskA));
futures.add(e.submit(taskB));
futures.add(e.submit(taskC));
// now call take() on the executor completion service,
// which will block the calling thread until the first task has completed
// either succesfully or abruptly (with an exception)
Future<Result> f = e.take();
在此之后,当您调用 时f.get()
,您将获得一个实例,Result
或者它会抛出一个ExectutionException
(包装执行抛出的异常)。任何一个都会立即发生(感谢执行者完成服务)。
然后您将做出相应的反应:如果f.get()
抛出异常,f
则从futures
集合中删除,遍历集合的其他元素(即通过您提交的其他任务),以及.cancel()
它们。Callable
s 必须被编码为可取消,否则调用将.cancel()
什么也不做。