java線程池源碼閱讀

說明

簡單理解和使用可以參考:https://www.cnblogs.com/LQBlog/p/8735356.html

類圖

接口

Executor接口

public interface Executor {
    /**
     * 代表提交了一個任務
     * @param command
     */
    void execute(Runnable command);
}

簡單的實現

1.希望同步執行任務的實現

public class SimpleExecutor implements Executor {
    @Override
    public void execute(Runnable command) {
        command.run();;
    }
}

2.基於線程運行任務的實現

public class ThreadExecutor implements Executor{
    @Override
    public void execute(Runnable command) {
        new Thread(command).start();
    }
}

ExecutorService接口

Executor太簡單了,只能提交任務,往往我們需要關注線程池狀態,執行了多少個任務,完成多少個任務,線程池塘線程數量等,Excutor不能滿足,所以需要看ExecutorService接口基於Executor的擴展public interface 

class ExecutorService extends Executor {
    /**
     * 關閉線程池,已提交的任務繼續執行,不接受繼續提交新任務
     */
    void shutdown();

    /**
     * 關閉線程池,嘗試停止正在執行的所有任務,不接受繼續提交新任務
     * 它和前面的方法相比,加了一個單詞“now”,區別在於它會去停止當前正在進行的任務
     *
     * @return
     */
    List<Runnable> shutdownNow();

    /**
     * 判斷線程池是否已關閉
     * @return
     */
    boolean isShutdown();

    /**
     * 如果調用了 shutdown() 或 shutdownNow() 方法後,所有任務結束了,那麼返回true
     * 這個方法必須在調用shutdown或shutdownNow方法之後調用纔會返回true
     */
    boolean isTerminated();


    /**
     * 等待所有任務完成,並設置超時時間
     * 我們這麼理解,實際應用中是,先調用 shutdown 或 shutdownNow,
     * 然後再調這個方法等待所有的線程真正地完成,返回值意味着有沒有超時 InterruptedException if interrupted while waiting
     */
    boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException;

    /**
     * 提交一個 Callable 任務 內部會包裝成Future
     */
    <T> Future<T> submit(Callable<T> task);

    /**
     * 提交一個 Runnable 任務,第二個參數將會放到 Future 中,作爲返回值,
     * 因爲 Runnable 的 run 方法本身並不返回任何東西 內部會用Future包裝
     */
    <T> Future<T> submit(Runnable task, T result);

    /**
     * 提交一個 Runnable 任務
     */
    Future<?> submit(Runnable task);

    /**
     * 執行所有任務,返回 Future 類型的一個 list*/
    <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;

    /**
     * 只有其中的一個任務結束了,就可以返回,返回執行完的那個任務的結果*/
    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
            throws InterruptedException, ExecutionException;

    /**
     * 同上一個方法,只有其中的一個任務結束了,就可以返回,返回執行完的那個任務的結果,
     * 不過這個帶超時,超過指定的時間,拋出 TimeoutException 異常*/
    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
}

AbstractExecutorService

是一個抽象類,對ExecutorService的相關方法進行了實現

public abstract class AbstractExecutorService implements ExecutorService {
    /**
     * 包裝成futureTask
     */
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }

    /**
     *  包裝成futureTask
     */
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }

    /**
     *  包裝成futureTask
     */
    public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        //具體執行任務交給子類執行
        execute(ftask);
        return ftask;
    }

    /**
     *  包裝成futureTask
     */
    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;
    }

    /**
     *  包裝成futureTask
     */
    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();
        //初始化task list容器
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
        //交給ExecutorCompletionService  只負責調度,最終內部執行任務還是調用的 this的execute
        ExecutorCompletionService<T> ecs =
                new ExecutorCompletionService<T>(this);
        try {
            ExecutionException ee = null;
            //是不是帶有超時時間的
            final long deadline = timed ? System.nanoTime() + nanos : 0L;
            Iterator<? extends Callable<T>> it = tasks.iterator();

            //預執行第一個任務 ecs.submit內部也是調用 當前對象的execute
            futures.add(ecs.submit(it.next()));
            //task數量-1
            --ntasks;
            //提交的任務數
            int active = 1;

            //遍歷
            for (;;) {
                //獲取執行結果內部是調用ecs completionQueue如果返回會將結果放入此queue
                Future<T> f = ecs.poll();
                //如果上一個任務沒有執行完畢,針對第一次則是與預執行那個任務,則繼續提交任務
                if (f == null) {
                    //表示還有任務 繼續提交任務
                    if (ntasks > 0) {
                        --ntasks;
                        futures.add(ecs.submit(it.next()));
                        ++active;
                    }
                    else if (active == 0)//當爲0 表示下面 f!=null 每次都異常 任務沒有了 結束
                        break;
                    else if (timed) {//當任務提交完畢,則最後調用poll嘗試等待指定時機
                        f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
                        if (f == null)//等待指定四航局 還未獲取到結果則拋出超時異常
                            throw new TimeoutException();
                        nanos = deadline - System.nanoTime();
                    }
                    else//非超時執行task
                        f = ecs.take();
                }
                //表示獲取到結果
                if (f != null) {
                    --active;//-1
                    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)
            throws InterruptedException, ExecutionException {
        try {
            //調用doInvokeAny
            return doInvokeAny(tasks, false, 0);
        } catch (TimeoutException cannotHappen) {
            assert false;
            return null;
        }
    }

    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> 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) {
                //包裝成future
                RunnableFuture<T> f = newTaskFor(t);
                //加入futures
                futures.add(f);
                //執行任務並調用子類的execute方法
                execute(f);
            }
            //遍歷檢查所有任務結果
            for (int i = 0, size = futures.size(); i < size; i++) {
                Future<T> f = futures.get(i);
                if (!f.isDone()) {
                    try {
                        // 這是一個阻塞方法,直到獲取到值,或拋出了異常
                        // 這裏有個小細節,其實 get 方法簽名上是會拋出 InterruptedException 的
                        // 可是這裏沒有進行處理,而是拋給外層去了。此異常發生於還沒執行完的任務被取消了
                        f.get();
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    }
                }
            }
            //表示都檢查完畢
            done = true;
            //返回結果
            return futures;
        } finally {
            //上面執行任務檢查並沒有cache所有異常,以及execute提交任務拒絕策略也會拋出異常,、針對這種情況取消其他任務
            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,
                                         long timeout, TimeUnit unit)
            throws InterruptedException {
        if (tasks == null)
            throw new NullPointerException();
        long nanos = unit.toNanos(timeout);
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
            for (Callable<T> t : tasks)
                futures.add(newTaskFor(t));

            //計算超時時間
            final long deadline = System.nanoTime() + nanos;
            final int size = futures.size();

            // Interleave time checks and calls to execute in case
            // executor doesn't have any/much parallelism.
            for (int i = 0; i < size; i++) {
                execute((Runnable)futures.get(i));
                //提交任務也要更新超時時間
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L)
                    return futures;
            }

            for (int i = 0; i < size; i++) {
                Future<T> f = futures.get(i);
                if (!f.isDone()) {
                    //超時時間爲0 返回所有任務
                    if (nanos <= 0L)
                        return futures;
                    try {
                        //嘗試等待,
                        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);
        }
    }

}

ExecutorCompletionService實現

public class ExecutorCompletionService<V> implements CompletionService<V> {
    //真正執行任務的地方 我們的線程池對象
    private final Executor executor;
    //線程池對象
    private final AbstractExecutorService aes;
    private final BlockingQueue<Future<V>> completionQueue;

    /**
     * 內部類實現了futureTask
     * 對RunnableFuture進行了增強
     */
    private class QueueingFuture extends FutureTask<Void> {
        QueueingFuture(RunnableFuture<V> task) {
            super(task, null);
            this.task = task;
        }

        /**
         * 增強方法
         */
        protected void done() {
            //任務執行完畢則將task加入completionQueue
            completionQueue.add(task);
        }
        private final Future<V> task;
    }

    private RunnableFuture<V> newTaskFor(Callable<V> task) {
        if (aes == null)
            return new FutureTask<V>(task);
        else
            //調用的我們線程池的newTaskFor方法包裝任務
            return aes.newTaskFor(task);
    }

    private RunnableFuture<V> newTaskFor(Runnable task, V result) {
        if (aes == null)
            return new FutureTask<V>(task, result);
        else
            //調用的我們線程池的newTaskFor方法包裝任務
            return aes.newTaskFor(task, result);
    }
    //構造方法
    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>>();
    }

    //構造方法 可以可以自己設置completionQueue
    public ExecutorCompletionService(Executor executor,
                                     BlockingQueue<Future<V>> 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<V> submit(Callable<V> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<V> f = newTaskFor(task);
        //最終還是委託給真正的線程池
        executor.execute(new java.util.concurrent.ExecutorCompletionService.QueueingFuture(f));
        return f;
    }

    public Future<V> submit(Runnable task, V result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<V> f = newTaskFor(task, result);
        //最終還是委託給真正的線程池
        executor.execute(new java.util.concurrent.ExecutorCompletionService.QueueingFuture(f));
        return f;
    }

    public Future<V> take() throws InterruptedException {
        //返回任務結果
        return completionQueue.take();
    }

    public Future<V> poll() {
        //返回任務結果
        return completionQueue.poll();
    }

    public Future<V> poll(long timeout, TimeUnit unit)
            throws InterruptedException {
        //返回任務結果
        return completionQueue.poll(timeout, unit);
    }

}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章