使用
ExecutorCompletionService.poll/take,您将
Future在完成时收到s(按完成顺序(或多或少))。使用
ExecutorService.invokeAll,您没有此功能;您可以阻塞直到全部完成,或者指定一个超时时间,在此之后取消不完整的操作。
static class SleepingCallable implements Callable<String> { final String name; final long period; SleepingCallable(final String name, final long period) { this.name = name; this.period = period; } public String call() { try { Thread.sleep(period); } catch (InterruptedException ex) { } return name; }}现在,在下面,我将演示如何
invokeAll工作:
final ExecutorService pool = Executors.newFixedThreadPool(2);final List<? extends Callable<String>> callables = Arrays.asList( new SleepingCallable("quick", 500), new SleepingCallable("slow", 5000));try { for (final Future<String> future : pool.invokeAll(callables)) { System.out.println(future.get()); }} catch (ExecutionException | InterruptedException ex) { }pool.shutdown();这将产生以下输出:
C:devscrap>java CompletionExample... after 5 s ...quickslow
使用
CompletionService,我们看到不同的输出:
final ExecutorService pool = Executors.newFixedThreadPool(2);final CompletionService<String> service = new ExecutorCompletionService<String>(pool);final List<? extends Callable<String>> callables = Arrays.asList( new SleepingCallable("slow", 5000), new SleepingCallable("quick", 500));for (final Callable<String> callable : callables) { service.submit(callable);}pool.shutdown();try { while (!pool.isTerminated()) { final Future<String> future = service.take(); System.out.println(future.get()); }} catch (ExecutionException | InterruptedException ex) { }这将产生以下输出:
C:devscrap>java CompletionExample... after 500 ms ...quick... after 5 s ...slow
请注意,时间是相对于程序启动的时间,而不是前一条消息。
您可以在此处找到完整的代码。



