【并发编程】-- AbstractExecutorService实现原理(1)

110 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第26天,点击查看活动详情

AbstractExecutorService实现原理

子类继承ExecutorService,使用模板方法,通过抽象类来实现部分公用算法,这样子类实现线程池就容易些。

抽象执行器服务部分源码如下:

public abstract class AbstractExecutorService implements ExecutorService {
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }
	protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }
    public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }
    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }
    /**
    	执行传入的任务,只要任何一个任务被执行完成就返回,然后取消其他任务,any指任何一个tasks中的任务执行完成,timed和nacos用来表明执行超时时间
    **/
    private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
                              boolean timed, long nanos)
        throws InterruptedException, ExecutionException, TimeoutException {
        //任务判空
        if (tasks == null)
            throw new NullPointerException();
        int ntasks = tasks.size();
        if (ntasks == 0)
            throw new IllegalArgumentException();
        //创建用于保存执行stub的future对象的集合
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
        //创建ExecutorCompletionService用于执行任务
        ExecutorCompletionService<T> ecs =
            new ExecutorCompletionService<T>(this);

        try {
            // 记录异常,这样如果不能获取任何result,可以抛出最后一个异常。
            ExecutionException ee = null;
            final long deadline = timed ? System.nanoTime() + nanos : 0L;
            //获取集合的迭代器
            Iterator<? extends Callable<T>> it = tasks.iterator();

            // 先开始一项任务,其余的增量执行
            futures.add(ecs.submit(it.next()));
            //任务数减1
            --ntasks;
            //正在执行的任务为1
            int active = 1;
}

解析方法如下:

newTaskFor(Runnable runnable, T value)方法:将Runnable对象封装为FutureTask。

newTaskFor(Callable callable)方法:将Callable对象封装为FutureTask。

submit(Runnable task)方法:封装Runnable task,然后调用execute执行。

submit(Runnable task, T result)方法:封装Runnable task,然后调用execute执行,注意点还封装了结果。

submit(Callable task)方法:封装Callable task,然后调用execute执行。