jdk8源码:concurrent包

这里分析一下concurrent包下的部分类!!!


1.Executor/ExecutorService

        线程资源比较重要,为了复用已经创建的线程,减少在创建和销毁线程时产生的性能开销。因为创建和管理线程非常心累,并且操作系统通常对线程数有限制,所以建议使用线程池来并发执行任务,而不是每次请求进来时创建一个线程。

        Executor:将任务本身和任务的执行分离(Thread而是将全部柔和到一起很不方面管理)。用于调度Runnable和Callable。

        ExecutorService :对Excetor进行扩展,提供了Future异步支持(任务提交后在需要时检查 Future是否有结果,其get() 方法是阻塞式的,如果调用时任务还没有完成,会等待直到任务执行结束)。

        接口源码如下:

//顶层接口
public interface Executor {
    //执行任务
    void execute(Runnable command);
}
//线程池接口
public interface ExecutorService extends Executor {
	//关闭线程池,不再接受新任务,等待所有任务完成
    void shutdown();
    //关闭线程池,不再接受新任务,返回等待执行的任务列表
    List<Runnable> shutdownNow();
    //线程池是否关闭
    boolean isShutdown();
    //线程池关闭,所有任务均完成则返回true
    boolean isTerminated();
    //阻塞,直到所有线程执行完毕或者超时
    boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
    //提交一个任务,交给线程池执行(callable自带返回结果)
    <T> Future<T> submit(Callable<T> task);
    //提交一个任务,交给线程池执行(runnable不自带返回结果,用result表示)
    <T> Future<T> submit(Runnable task, T result);
    //提交一个任务交给线程池执行,并返回该任务的future
    Future<?> submit(Runnable task);
    //执行给定任务集合(可指定超时时间),全部完成(未抛出异常),返回future集合
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;
    //执行给定任务(可指定超时时间),完成(未抛出异常),返回future
    <T> T invokeAny(Collection<? extends Callable<T>> tasks)  throws InterruptedException, ExecutionException;
    <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}

2.AbstractExecutorService

        首先简单看一下任务相关的接口和实现类。

        Future接口:用来实现异步任务获取任务结果。Callable任务返回Future对象。源码如下:

public interface Future<V> {
	//尝试取消任务
    boolean cancel(boolean mayInterruptIfRunning);
    //如果任务正常完成前被取消,则返回true
    boolean isCancelled();
    //如果任务完成,则返回true
    boolean isDone();
    //查询结果(一直阻塞到任务返回结果)
    V get() throws InterruptedException, ExecutionException;
    //查询结果(一直阻塞到指定时间)
    V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;
}

        Runnable接口:用来创建任务。源码如下:

public interface Runnable {
    //任务执行体
    public abstract void run();
}

        RunnableFuture接口:Future和Runnable的子接口。任务的创建、异步支持。源码如下:

public interface RunnableFuture<V> extends Runnable, Future<V> {
    //任务执行体
    void run();
}

        FutureTask类:RunnableFuture的接口实现类。是一个支持取消的异步任务执行器,支持Callable或者Runnable类型任务的执行。源码后续单独分析。

        AbstractExecutorService给出ExecutorService的一个抽象实现。用于异步任务、任务执行的调度管理等。依次分析相关方法。

        创建任务,使用任务来构造FutureTask并返回,源码如下:

	//创建任务
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
    	//构造器中value用来保存任务返回结果
        return new FutureTask<T>(runnable, value);
    }
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }
    

        提交任务,就是调用execute(),传入任务进行执行,这里交给子类实现。源码如下:

    //提交任务
    public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        //抽象类没有实现execute(),这里交给子类实现
        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;
    }

        执行给定任务集合,返回一个已经成功完成的任务的结果(任务得到结果、没有抛出异常视为执行成功)。源码如下:

    //执行任务集合,返回第一个执行成功的结果
    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();
        //构造futures集合
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
        //ExecutorCompletionService可以使用阻塞队列来保存多个线程的执行结果(future类型)
        ExecutorCompletionService<T> ecs = new ExecutorCompletionService<T>(this);
        try {

            ExecutionException ee = null;
            //超时时间的nanos表示
            final long deadline = timed ? System.nanoTime() + nanos : 0L;
            Iterator<? extends Callable<T>> it = tasks.iterator();
            //ExecutorCompletionService提交任务返回future,然后添加到集合中
            futures.add(ecs.submit(it.next()));
            --ntasks;
            int active = 1;
            for (;;) {
            	//轮询队列中已经完成的任务,弹出其future然后从队列中删除
                Future<T> f = ecs.poll();
                //future为空,调用阻塞队列的take获取对应线程的执行结果
                if (f == null) {
                    if (ntasks > 0) {
                        --ntasks;
                        futures.add(ecs.submit(it.next()));
                        ++active;
                    }
                    else if (active == 0)
                        break;
                    else if (timed) {
                        f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
                        if (f == null)
                            throw new TimeoutException();
                        nanos = deadline - System.nanoTime();
                    }
                    else
                        f = ecs.take();
                }
                //future不为空,get其结果
                if (f != null) {
                    --active;
                    try {
                        return f.get();
                    } catch (ExecutionException eex) {
                        ee = eex;
                    } catch (RuntimeException rex) {
                        ee = new ExecutionException(rex);
                    }
                }
            }
            if (ee == null)
                ee = new ExecutionException();
            throw ee;

        } finally {
            for (int i = 0, size = futures.size(); i < size; i++)
                futures.get(i).cancel(true);
        }
    }


    //执行任务集合,返回一个已经成功任务的结果(支持超时时间)
    public <T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
    	//doInvokeAny()
        return doInvokeAny(tasks, true, unit.toNanos(timeout));
    }
    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
            throws InterruptedException, ExecutionException {
            try {
            	//doInvokeAny()
                return doInvokeAny(tasks, false, 0);
            } catch (TimeoutException cannotHappen) {
                assert false;
                return null;
            }
        }

        执行给定任务,所有任务成功完成()则返回其future集合。源码如下:

    //执行任务集合,返回任务的Future集合(支持超时时间)
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)
        throws InterruptedException {
        if (tasks == null)
            throw new NullPointerException();
        long nanos = unit.toNanos(timeout);
        //构造future集合
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
            for (Callable<T> t : tasks)
            	//newTaskFor()将Callable类型转化为FutureTask类型,并添加到futures集合中
                futures.add(newTaskFor(t));
            final long deadline = System.nanoTime() + nanos;
            final int size = futures.size();
            //执行所有任务
            for (int i = 0; i < size; i++) {
            	//这里调用execute()
                execute((Runnable)futures.get(i));
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L)
                    return futures;
            }
            //调用所有future的get,阻塞获取任务结果
            for (int i = 0; i < size; i++) {
                Future<T> f = futures.get(i);
                if (!f.isDone()) {
                    if (nanos <= 0L)
                        return futures;
                    try {
                    	//FutureTask调用get获取任务结果
                        f.get(nanos, TimeUnit.NANOSECONDS);
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    } catch (TimeoutException toe) {
                        return futures;
                    }
                    nanos = deadline - System.nanoTime();
                }
            }
            done = true;
            return futures;
        } finally {
            if (!done)
                for (int i = 0, size = futures.size(); i < size; i++)
                    futures.get(i).cancel(true);
        }
    }
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
            throws InterruptedException {
            if (tasks == null)
                throw new NullPointerException();
            ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
            boolean done = false;
            try {
                for (Callable<T> t : tasks) {
                    RunnableFuture<T> f = newTaskFor(t);
                    futures.add(f);
                    execute(f);
                }
                for (int i = 0, size = futures.size(); i < size; i++) {
                    Future<T> f = futures.get(i);
                    if (!f.isDone()) {
                        try {
                            f.get();
                        } catch (CancellationException ignore) {
                        } catch (ExecutionException ignore) {
                        }
                    }
                }
                done = true;
                return futures;
            } finally {
                if (!done)
                    for (int i = 0, size = futures.size(); i < size; i++)
                        futures.get(i).cancel(true);
            }
        }
}

3.ThreadPoolExecutor

一般线程池包含三部分:调度器、线程队列、任务队列。其中调度器将任务队列中的任务分配给线程队列中的线程去执行,执行完毕之后线程又会到线程队列中。

ThreadPoolExecutor是AbstractExecutorService的直接子类。提供了最基础的线程池功能。ThreadPoolExecutor就没有调度器,线程队列中的所有线程自动去获取任务队列中的任务进行执行。可见核心其实就是自动控制线程队列长度与任务队列长度相匹配,从而使任务按顺序合理执行。其中线程队列存放当前正在处理任务的线程或者空闲线程,任务队列存放待执行任务(正在被线程执行的任务是不在任务队列中的)。

使用corePoolSize(合理容量)、maximumPoolSize(最大容量)来控制线程队列的长度,每当调用execute(Runnable)提交新任务到线程池中会自动调整线程个数,就是如果来了新任务,线程优先增长到合理的个数,之后再来新任务则优先加入任务队列,任务队列放不下则线程个数增长到最大个数。如下:
如果还没超过合理容量:则需要新建线程来处理新任务
如果超过最合理容量且小于最大容量:任务队列未满则新任务放到任务队列中,任务队列满了则新建线程来处理新任务
如果等于最大容量:任务队列未满则新任务放到任务队列中,任务队列满了则执行拒绝策略(RejectedExecutionHandler )




猜你喜欢

转载自blog.csdn.net/qq_34448345/article/details/80087738