案例:
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(内存溢出)的情况