问题
- 使用 Future.get()异步获取结果的时候,当异步任务没有计算成功,主线程调用 get()方法获取结果的时候会一直阻塞到线程完成为止,影响运行效率。
- 我们习惯使用线程池达到线程的复用,线程池中使用 submit 异步计算任务获取返回结果的时候,我们可能 future.get()方式获取任务的返回结果,但是 N 个线程去执行,当前任务没有执行完成,而其他任务执行完事了,我们通过 future.get()方式获取结果的时候即使其他完事了,我们还需要等待这个任务完成,影响效率,我们希望可以这样,谁先完成,谁就可以获取结果,CompleService 就干这个事的。
实现原理
我们一般使用 CompletionService 的子类 ExecutorCompletionService,其内部有一个阻塞队列,传入 N 个任务,任意任务完成之后,会将执行结果放入阻塞队列中,其他线程可以调用 take,poll 方法从阻塞队列中获取任务,任务进出队列遵循先进先出的原则。
例子
//例子打印结果会是先完成的先打印
public static void main(String[] args) throws Exception{
//初始化线程池
ExecutorService threadPool = Executors.newFixedThreadPool(5);
// 同时运行多个任务
CompletionService<String> completionService = new Execut