【JDK源碼分析系列】ThreadPoolExecutor 源碼解析 -- ThreadPoolExecutor 的類結構

【JDK源碼分析系列】ThreadPoolExecutor 源碼解析 -- ThreadPoolExecutor 的類結構

【1】線程池整體執行流程圖示

線程池相關詳細介紹參見 【JAVA併發編程系列】併發框架 -- Executor 框架(線程池)

【2】ThreadPoolExecutor 的類結構

【2.1】Executor

// Executor:定義 execute 方法來執行任務,入參是 Runnable,無出參
public interface Executor {
    void execute(Runnable command);
}

【2.2】ExecutorService

public interface ExecutorService extends Executor {

    // 關閉,不會接受新的任務,也不會等待未完成的任務
    // 如果需要等待未完成的任務,可以使用 awaitTermination 方法
    void shutdown();

    // 試圖關閉所有正在執行的任務,返回等待執行的任務列表
    List<Runnable> shutdownNow();

    // 判斷 executor 是否關閉了,true 已關閉
    boolean isShutdown();

    // 所有的任務是否都已經終止,是的話,返回 true
    boolean isTerminated();

    // 在超時時間內阻塞,等待所有的任務執行完成
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;

    // 提交有返回值的任務,使用 get 方法可以阻塞等待任務的結果返回
    <T> Future<T> submit(Callable<T> task);

    // 提交有返回值的任務,使用 get 方法可以阻塞等待任務的結果返回
    <T> Future<T> submit(Runnable task, T result);

    // 提交沒有返回值的任務
    // 任務執行完成之後,返回 null 值
    Future<?> submit(Runnable task);

    // 給定任務集合,返回已經執行完成的 Future 集合,每個返回的 Future 都是 isDone = true 的狀態
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;

    // 給定任務集合,返回已經執行完成的 Future 集合,每個返回的 Future 都是 isDone = true 的狀態
    // 該方法具有 TimeOut 判斷
    <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;

    // 給定任務中有一個執行成功就返回,如果拋異常,其餘未完成的任務將被取消
    // 該方法具有 TimeOut 判斷
    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

【2.3】AbstractExecutorService

AbstractExecutorService 是一個抽象類,封裝了 Executor 的很多通用功能。

【2.3.1】AbstractExecutorService -- newTaskFor

// 把 Runnable 轉化成 RunnableFuture
// RunnableFuture 是一個接口,實現了 Runnable 和 Future
// FutureTask 是 RunnableFuture 的實現類,主要是對任務進行各種管理
// Runnable + Future => RunnableFuture => FutureTask
// FutureTask 其本身就是一個任務,而且具備對任務管理的功能,
// 比如可以通過 get 方法拿到任務的執行結果
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
    return new FutureTask<T>(runnable, value);
}

// 把 Runnable 轉化成 RunnableFuture
// RunnableFuture 是一個接口,實現了 Runnable 和 Future
// FutureTask 是 RunnableFuture 的實現類,主要是對任務進行各種管理
// Runnable + Future => RunnableFuture => FutureTask
// FutureTask 其本身就是一個任務,而且具備對任務管理的功能,
// 比如可以通過 get 方法拿到任務的執行結果
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
    return new FutureTask<T>(callable);
}

【2.3.2】AbstractExecutorService -- submit

// submit 方法是使用線程池時提交任務的方法,支持 Runable 和 Callable 兩種任務的提交,
// 方法中 execute 方法是其子類 ThreadPoolExecutor 實現的,不管是哪種任務入參,
// execute 方法最終執行的任務都是 FutureTask
//
// 提交無返回值的 Runnable 任務
public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    // ftask 其實是 FutureTask
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}

// 提交有返回值的 Runnable 任務,
// task 是 Runnable 類型在 FutureTask 中進行向 Callable 的轉換
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;
}

// 提交 Callable 任務
public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
}

【2.3.3】AbstractExecutorService -- invokeAny

// 給定任務中有一個執行成功就返回,
// 一旦invokeAny方法正常返回或者拋出異常,那些沒有完成的任務將被取消
public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
    throws InterruptedException, ExecutionException {
    try {
        // 具體執行方法
        return doInvokeAny(tasks, false, 0);
    } catch (TimeoutException cannotHappen) {
        assert false;
        return null;
    }
}

// 給定任務中有一個執行成功就返回,
// 一旦invokeAny方法正常返回或者拋出異常,那些沒有完成的任務將被取消
// 帶有超時處理
public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                        long timeout, TimeUnit unit)
    throws InterruptedException, ExecutionException, TimeoutException {
    // 具體執行方法
    return doInvokeAny(tasks, true, unit.toNanos(timeout));
}
// invokeAny 具體實現方法
private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
                            boolean timed, long nanos)
    throws InterruptedException, ExecutionException, TimeoutException {
    if (tasks == null)
        throw new NullPointerException();
    // 獲取 task 的數量
    int ntasks = tasks.size();
    if (ntasks == 0)
        throw new IllegalArgumentException();
    // ArrayList 緩存 Future 結構變量
    ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
    // ExecutorCompletionService 類
    // 內部屬性
    // private final Executor executor;
    // private final AbstractExecutorService aes;
    // private final BlockingQueue<Future<V>> completionQueue;
    //
    // 構造函數
    // 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>>();
    // }
    ExecutorCompletionService<T> ecs =
        new ExecutorCompletionService<T>(this);

    try {
        // Record exceptions so that if we fail to obtain any
        // result, we can throw the last exception we got.
        ExecutionException ee = null;
        final long deadline = timed ? System.nanoTime() + nanos : 0L;
        Iterator<? extends Callable<T>> it = tasks.iterator();

        // Start one task for sure; the rest incrementally
        //
        // 此處提交一個可排隊的 FutureTask
        // public Future<V> submit(Callable<V> task) {
        //     if (task == null) throw new NullPointerException();
        //     RunnableFuture<V> f = newTaskFor(task);
        //     executor.execute(new QueueingFuture(f));
        //     return f;
        // }
        //
        // private class QueueingFuture extends FutureTask<Void> {
        //     QueueingFuture(RunnableFuture<V> task) {
        //         super(task, null);
        //         this.task = task;
        //     }
        //     // 實現了 FutureTask 中的 done 方法, 將 FutureTask 添加到阻塞隊列中
        //     // 在 FutureTask 的 finishCompletion() 調用
        //     protected void done() { completionQueue.add(task); }
        //     private final Future<V> task;
        // }
        futures.add(ecs.submit(it.next()));
        --ntasks;
        int active = 1;

        for (;;) {
            // 嘗試從阻塞隊列中獲取 FutureTask
            // poll(time):
            // 取走BlockingQueue裏排在首位的對象,若不能立即取出,
            // 則可以等time參數規定的時間,取不到時返回null
            Future<T> f = ecs.poll();
            if (f == null) {
                if (ntasks > 0) {
                    --ntasks;
                    futures.add(ecs.submit(it.next()));
                    ++active;
                }
                else if (active == 0)
                    break;
                else if (timed) {
                    // 嘗試從阻塞隊列中獲取 FutureTask
                    // poll(time):
                    // 取走BlockingQueue裏排在首位的對象,若不能立即取出,
                    // 則可以等time參數規定的時間,取不到時返回null
                    f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
                    if (f == null)
                        throw new TimeoutException();
                    nanos = deadline - System.nanoTime();
                }
                else
                    // take():取走BlockingQueue裏排在首位的對象,若BlockingQueue爲空,
                    // 阻塞i進入等待狀態直到Blocking有新的對象被加入爲止
                    f = ecs.take();
            }
            if (f != null) {
                --active;
                try {
                    // 返回 FutureTask 中的結果
                    // 1.try 或 catch 中都有 return語句,並且有 finally,
                    //    最終先執行 finally,再執行 try 或 catch中的 return語句
                    // 2.try 或 catch 中都有 return語句,並且有 finally,
                    //    而且 finally中 有return語句 的話,最終先執行 finally,
                    //    然後執行 finally中 有return語句,並不會執行 try 或 catch 中return語句
                    // 3.try 或 catch 中都有 return語句,並且有 finally,而且 finally中 對try 或 catch 中的 
                    //    return語句所返回的基本類型變量/引用類型變量 進行了重新賦值,
                    //    即使如此,也只會返回 try 或 catch 中的return語句所返回的基本類型變量/引用類型變量的值,
                    //    finally中的修改try 或 catch 中的返回值操作並不會生效
                    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++)
            //移除 ArrayList 中的 FutureTask
            futures.get(i).cancel(true);
    }
}

【2.3.4】AbstractExecutorService -- invokeAll

// 給定任務集合,返回已經執行完成的 Future 集合,每個返回的 Future 都是 isDone = true 的狀態
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
    throws InterruptedException {
    if (tasks == null)
        throw new NullPointerException();
    //新建一個 tasks.size() 的 ArrayList 用於緩存 FutureTask
    ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
    boolean done = false;
    try {
        //遍歷 tasks 將其中的 FutureTask 加入到 futures
        for (Callable<T> t : tasks) {
            RunnableFuture<T> f = newTaskFor(t);
            futures.add(f);
            //執行 FutureTask
            execute(f);
        }
        //遍歷 futures 嘗試獲取執行結果
        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;
        //返回所有 FutureTask 的執行結果
        return futures;
    } finally {
        if (!done)
        //該 if 判斷成立表示出現了異常情況需要取消 FutureTask
            for (int i = 0, size = futures.size(); i < size; i++)
                futures.get(i).cancel(true);
    }
}


// 給定任務集合,返回已經執行完成的 Future 集合,每個返回的 Future 都是 isDone = true 的狀態
// 帶有超時處理 timeout 爲所有任務執行完畢的截止時間限制
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                        long timeout, TimeUnit unit)
    throws InterruptedException {
    if (tasks == null)
        throw new NullPointerException();
    //TimeOut 記錄變量
    long nanos = unit.toNanos(timeout);
    //新建一個 tasks.size() 的 ArrayList 用於緩存 FutureTask
    ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
    boolean done = false;
    try {
        //遍歷 tasks 將其中的 FutureTask 加入到 futures
        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.
        // 遍歷執行 futures 中的 FutureTask
        for (int i = 0; i < size; i++) {
            execute((Runnable)futures.get(i));
            nanos = deadline - System.nanoTime();
            if (nanos <= 0L)
                // 若超時則之間返回 futures 此時 done 爲 false 
                // 則會在 finally 代碼塊中取消 FutureTask 任務
                return futures;
        }

        for (int i = 0; i < size; i++) {
            Future<T> f = futures.get(i);
            if (!f.isDone()) {
                if (nanos <= 0L)
                    // 超時則返回 futures
                    return futures;
                try {
                    // 帶超時的獲取執行結果
                    f.get(nanos, TimeUnit.NANOSECONDS);
                } catch (CancellationException ignore) {
                } catch (ExecutionException ignore) {
                } catch (TimeoutException toe) {
                    // 若超時則之間返回 futures 此時 done 爲 false 
                    // 則會在 finally 代碼塊中取消 FutureTask 任務
                    return futures;
                }
                nanos = deadline - System.nanoTime();
            }
        }
        done = true;
        // 若超時則之間返回 futures 此時 done 爲 true 
        // 任務不會被取消返回正常執行的結果
        return futures;
    } finally {
        if (!done)
            for (int i = 0, size = futures.size(); i < size; i++)
                futures.get(i).cancel(true);
    }
}

參考致謝
本博客爲博主的學習實踐總結,並參考了衆多博主的博文,在此表示感謝,博主若有不足之處,請批評指正。

【1】37 ThreadPoolExecutor 源碼解析

【2】Java併發編程的藝術

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