ExecutorCompletionService源码分析

概述

在使用线程池批量提交task后,如果想要按照future完成的顺序依次处理future,可以通过ExecutorCompletionService实现以上场景。ExecutorCompletionService的实现原理是:

  • 维护一个BlockingQueue<Future<V>>队列,在future完成后,将future添加到该队列中。ExecutorCompletionService默认使用LinkedBlockingQueue<Future<V>>队列,该队列具有FIFO特性,从而实现先完成的future先被处理。
  • 基于代理模式,代理executor的execute()方法。

使用示例

void solve(Executor e,
            Collection<Callable<Result>> solvers)
     throws InterruptedException, ExecutionException {
     CompletionService<Result> ecs
         = new ExecutorCompletionService<Result>(e);
     for (Callable<Result> s : solvers)
         ecs.submit(s);
     int n = solvers.size();
     for (int i = 0; i < n; ++i) {
         Result r = ecs.take().get();
         if (r != null)
             use(r);
     }
 }

成员变量

//被代理的executor  
  private final Executor executor;
    private final AbstractExecutorService aes;
//记录已经完成的future的阻塞队列
    private final BlockingQueue<Future<V>> completionQueue;

构造函数

/**
     * Creates an ExecutorCompletionService using the supplied
     * executor for base task execution and a
     * {@link LinkedBlockingQueue} as a completion queue.
     *
     * @param executor the executor to use
     * @throws NullPointerException if executor is {@code null}
     */
    public ExecutorCompletionService(Executor executor) {
        if (executor == null)
            throw new NullPointerException();
        this.executor = executor;
        this.aes = (executor instanceof AbstractExecutorService) ?
            (AbstractExecutorService) executor : null;
        this.completionQueue = new LinkedBlockingQueue<Future<V>>();
    }

QueueingFuture

QueueingFuture的作用是在future完成后,将之添加到queue中

/**
     * FutureTask extension to enqueue upon completion
     */
    private class QueueingFuture extends FutureTask<Void> {
        QueueingFuture(RunnableFuture<V> task) {
            super(task, null);
            this.task = task;
        }
        protected void done() { completionQueue.add(task); }
        private final Future<V> task;
    }

submit()方法

public Future<V> submit(Callable<V> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<V> f = newTaskFor(task);
//代理executor的execute方法
        executor.execute(new QueueingFuture(f));
        return f;
    }


private RunnableFuture<V> newTaskFor(Callable<V> task) {
        if (aes == null)
            return new FutureTask<V>(task);
        else
            return aes.newTaskFor(task);
    }

take方法

public Future<V> take() throws InterruptedException {
//从阻塞队列中取出一个已经完成的future
        return completionQueue.take();
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值