ExecutorCompletionService

ExecutorCompletionService
当你需要使用Executor执行一个批量处理的任务,并且希望有返回值时,可能会使用Future不断的判断是否已经完成。
现在有一个更好的方案就是CompletionService,它整合了Executor和BlockingQueue的功能。
Future<V> submit(Callable<V> task);
Future<V> take() throws InterruptedException;
Future<V> poll();
Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException;
从API中可以直观的看出,可以将Callable任务提交给CompletionService去执行,然后在需要使用返回值的时候调用
take()或poll()方法(一个阻塞一个非阻塞)获取结果。

ExecutorCompletionService是实现了CompletionService接口的类,它在构造方法中创建了一个BlockingQueue,
private final BlockingQueue<Future<V>> completionQueue;

然后把所有提交的任务都包装成一个QueueingFuture
private class QueueingFuture extends FutureTask<Void> {
        QueueingFuture(RunnableFuture<V> task) {
            super(task, null);
            this.task = task;
    }

然后重写了Future中的done方法,将任务执行后的结果放到BlockingQueue中
protected void done() { 
completionQueue.add(task); 
}

使用上跟CompletionService是一样的

例如并行多个任务并获取返回值
public static void main (String[] args) throws InterruptedException, ExecutionException
{
ExecutorService pool = Executors.newFixedThreadPool(5);
ExecutorCompletionService<String> service = new ExecutorCompletionService<>(pool);
Integer taskCount = 5;

for(int i=0; i<taskCount; i++) {
int finalI = i;
service.submit(() ->
{
Thread.sleep(new Random().nextInt(5000));
return Thread.currentThread().getName() + "---finish ---Task---" + finalI;
});
}

int doneTask = 0;
while(doneTask < taskCount) {
Future<String> result = service.take();
System.out.println("resultTask: " + result.get());
doneTask++;
}
pool.shutdown();

}

打印结果
resultTask: pool-1-thread-2---finish ---Task---1
resultTask: pool-1-thread-3---finish ---Task---2
resultTask: pool-1-thread-5---finish ---Task---4
resultTask: pool-1-thread-1---finish ---Task---0
resultTask: pool-1-thread-4---finish ---Task---3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值