一.简介
- CompletionService的应用场景:批量提交异步任务。
- CompletionService将线程池Executor和阻塞队列BlockingQueue融合在一起,使得批量异步任务的管理更简单。
- CompletionService能够让异步任务的执行结果有序化,先执行完的先进入阻塞队列,避免无谓的等待。
二.API
接口
public interface CompletionService<V> {
// 提交Callable类型的任务
Future<V> submit(Callable<V> task);
// 提交Runnable类型的任务
Future<V> submit(Runnable task, V result);
// 获取并删除已完成状态的任务,如果没有则等待
Future<V> take() throws InterruptedException;
// 获取并删除已完成状态的任务,如果目前不存在这样的task,返回null
Future<V> poll();
// 获取并删除已完成状态的任务,必要时等待指定的等待时间(如果尚未存在)
Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException;
}
目前在 JDK8 中 CompletionService 接口只有一个实现类 ExecutorCompletionService
三.示例
take()方法取得最先完成任务的Future对象,谁执行时间最短谁最先返回。
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService service = Executors.newCachedThreadPool();
ExecutorCompletionService<String> completionService = new ExecutorCompletionService<>(service);
for (int i = 0; i < 100; i++) {
completionService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
int sleepValue = new Random().nextInt(5);
System.out.println("sleep = " + sleepValue + ", name: " + Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(sleepValue);
return "huhx: " + sleepValue + ", " + Thread.currentThread().getName();
}
});
}
for (int i = 0; i < 100; i++) {
System.out.println(completionService.take().get());
}
service.shutdown();
}
结果
sleep = 3, name: pool-1-thread-72
sleep = 1, name: pool-1-thread-77
sleep = 1, name: pool-1-thread-73
sleep = 0, name: pool-1-thread-80
sleep = 0, name: pool-1-thread-75
sleep = 3, name: pool-1-thread-80
huhx: 0, pool-1-thread-12
sleep = 1, name: pool-1-thread-76
sleep = 2, name: pool-1-thread-60
huhx: 0, pool-1-thread-20
sleep = 3, name: pool-1-thread-79
huhx: 0, pool-1-thread-24
公众号
微信号:bigdata_limeng