案例:
public static void main(String[] args) throws Exception {ExecutorService executorService = Executors.newCachedThreadPool();ArrayList<Future<Integer>> list = new ArrayList<>();Future<Integer> future_15 = executorService.submit(() -> {TimeUnit.SECONDS.sleep(15);System.out.println("执行时长为15s的执行完成。");return 15;});list.add(future_15);Future<Integer> future_5 = executorService.submit(() -> {TimeUnit.SECONDS.sleep(5);System.out.println("执行时长为5s的执行完成。");return 5;});list.add(future_5);Future<Integer> future_10 = executorService.submit(() -> {TimeUnit.SECONDS.sleep(10);System.out.println("执行时长为10s的执行完成。");return 10;});list.add(future_10);System.out.println("开始准备获取结果");for (Future<Integer> future : list) {System.out.println("future.get() = " + future.get());}Thread.currentThread().join();}
上述代码输出结果:
可以看到 耗时最长的最先获取结果,让耗时短的线程等着耗时长的线程
修改 使用【ExecutorCompletionService】提交任务:
public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService executorService = Executors.newCachedThreadPool();ExecutorCompletionService<Integer> completionService =new ExecutorCompletionService<>(executorService);completionService.submit(() -> {TimeUnit.SECONDS.sleep(15);System.out.println("执行时长为【15】的执行完成。");return 15;});completionService.submit(() -> {TimeUnit.SECONDS.sleep(5);System.out.println("执行时长为【5】的执行完成。");return 5;});completionService.submit(() -> {TimeUnit.SECONDS.sleep(10);System.out.println("执行时长为【10】的执行完成。");return 10;});System.out.println("开始准备获取结果");//循环3次是因为上面提交了3个异步任务for (int i = 0; i < 3; i++) {Integer returnStr = completionService.take().get();System.out.println("future.get() = " + returnStr);}Thread.currentThread().join();}
运行结果:
可以看出最先执行结束的线程,最先获取结果。
注意:当任务不需要返回值使不要使用 ExecutorCompletionService 来提交任务,因为ExecutorCompletionService 里有一个队列,当不关心返回值时,不会处理这个队列,这个队列就会越积越多,造成OOM(内存溢出)的情况