源码解析之CompleteService生产者消费者接口

CompleteService是一个生产者消费者接口,用来使生产和消费分离,生产者通过submit()方法用来提交任务,消费者通过take()方法获取执行完成的任务。CompleteService通常用来管理异步任务的IO队列,生产者和消费者可以属于系统的不同部分,具有生产者消费者类型的需求都可以考虑用这个模型来处理,Future控制任务的取消执行,以及执行完毕时候结果的获取,以及管理结果获取队列。

通过Excutor去执行任务,

public interface CompleteService{

Future submit(Callable task);//提交一个任务,这个任务可能被执行也可能被取消执行,当任务为空的时候抛出空指针异常,当任务不会调度执行的时候会抛出RejectedExecutionException.

Futuresubmit(Runnable task,V result);

Future take() throws InterruptedException;//检索下一个任务的Future并返回,如果没有检索到下个任务的Future就等待,如果等待的时候被Interrupt了就抛出InterruptedException

Future poll()://检索下一个任务的Future并返回,如果没有检索到下个任务的Future就返回空

Futurepoll(long timeout,TimeUnit timeUnit) throws InterruptedException;//检索下一个任务的Future并返回,如果没有检索到下个任务的Future,就等待timeout时间,没等到就返回空,等待过程中线程被Interrupt 就抛出InterruptedException
}

CompleteService的实现类,三个成员变量,用来执行任务的执行器,用来创建Future的,用来存储执行结果的内部队列。

public class ExecutorCompletionService implements CompletionService {
    private final Executor executor;//执行器
    private final AbstractExecutorService aes;//调用这个的创建Future的方法
    private final BlockingQueue> completionQueue;//内部队列

    /**
     * FutureTask extension to enqueue upon completion.
     */
    private static class QueueingFuture extends FutureTask {
        QueueingFuture(RunnableFuture task,
                       BlockingQueue> completionQueue) {
            super(task, null);
            this.task = task;
            this.completionQueue = completionQueue;//任务执行的队列
        }
        private final Future task;
        private final BlockingQueue> completionQueue;
        protected void done() { completionQueue.add(task); //外部调用,因为是protected的,Executor执行完任务后,将结果放进completionQueue里面
      }
    }

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

    private RunnableFuture newTaskFor(Runnable task, V result) {
        if (aes == null)
            return new FutureTask(task, result);
        else
            return aes.newTaskFor(task, result);
    }

    /**
     * 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>();
    }

    /**
     * Creates an ExecutorCompletionService using the supplied
     * executor for base task execution and the supplied queue as its
     * completion queue.
     *
     * @param executor the executor to use
     * @param completionQueue the queue to use as the completion queue//任务结束队列
     *        normally one dedicated for use by this service. This
     *        queue is treated as unbounded -- failed attempted
     *        {@code Queue.add} operations for completed tasks cause
     *        them not to be retrievable.
     * @throws NullPointerException if executor or completionQueue are {@code null}
     */
    public ExecutorCompletionService(Executor executor,
                                     BlockingQueue> completionQueue) {
        if (executor == null || completionQueue == null)
            throw new NullPointerException();
        this.executor = executor;
        this.aes = (executor instanceof AbstractExecutorService) ?
            (AbstractExecutorService) executor : null;
        this.completionQueue = completionQueue;
    }

    public Future submit(Callable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture f = newTaskFor(task);
        executor.execute(new QueueingFuture(f, completionQueue));
        return f;
    }

    public Future submit(Runnable task, V result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture f = newTaskFor(task, result);
        executor.execute(new QueueingFuture(f, completionQueue));
        return f;
    }

    public Future take() throws InterruptedException {
        return completionQueue.take();
    }

    public Future poll() {
        return completionQueue.poll();
    }

    public Future poll(long timeout, TimeUnit unit)
            throws InterruptedException {
        return completionQueue.poll(timeout, unit);
    }

}

你可能感兴趣的:(源码解析之CompleteService生产者消费者接口)