jdk源碼解析五之Executor框架


Executor基於生產者消費者模式,提交任務操作相當於生產者,執行任務的線程相當於消費者

線程不能不停創建,所以複用線程衍生出了線程池的概念,而不停的複用線程,假如有10個線程去跑100請求,還有90請求怎麼辦?引入了阻塞隊列.而如果10個線程最多隻能處理100線程,那101線程怎麼辦?這裏就引入new ThreadPoolExecutor.CallerRunsPolicy()4種處理的概念

開啓多少線程,最大多少線程,?
線程的任務使FIFO,LIFO還是按照優先級執行?
多餘的任務,是否阻塞隊列緩存?
隊列撐爆了,使用何種策略處理?
取消的時候,平滑過渡,還是強制終止所有任務?
出現異常,可定義異常處理器setDefaultUncaughtExceptionHandler/setUncaughtExceptionHandler

如何設計線程池大小?
Runtime.getRuntime().availableProcessors();
計算密集型,線程大小爲N+1(多一個備份競爭)
包含I/O或者其他阻塞任務
N=cpu個數 Runtime.availableProcessors
U=CPU利用率 0<=U<=1
W/C=任務等待時間/計算時間
線程池最優大小=NU(1+W/C)
資源:該資源的可用總量/每個任務對該資源的需求量

Executor

在這裏插入圖片描述

ExecutorService

提供了管理終止的方法,以及可爲跟蹤一個或多個異步任務執行狀況而生成 Future 的方法。

在這裏插入圖片描述

ScheduledExecutorService

對可調度的支持

在這裏插入圖片描述

AbstractExecutorService

在這裏插入圖片描述

    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        //底層封裝FutureTask
        return new FutureTask<T>(runnable, value);
    }

  public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        //子類實現
        execute(ftask);
        return ftask;
    }

  //返回最快的結果
    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;
        }
    }

 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();

        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
        //使用ExecutorCompletionService,獲取結果前阻塞.內部維護一個阻塞隊列,繼承Future保存結果
        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();
            //結果封裝到集合
            futures.add(
                    //執行回調函數
                    ecs.submit(it.next())
            );
            --ntasks;
            //記錄執行的回調函數個數
            int active = 1;

            for (;;) {
                //獲取結果,非阻塞
                Future<T> f = ecs.poll();
                //尚未獲取結果
                if (f == null) {
                    //回調任務>1,則繼續執行下一個回調任務
                    if (ntasks > 0) {
                        --ntasks;
                        futures.add(ecs.submit(it.next()));
                        //記錄正在執行個數
                        ++active;
                    }
                    else if (active == 0)
                        //正在執行個數爲0,則說明獲取結果階段拋出異常,直接結束
                        break;
                    else if (timed) {
                        //如果阻塞,則設置超時獲取結果
                        f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
                        if (f == null)
                            throw new TimeoutException();
                        //超時時間減少
                        nanos = deadline - System.nanoTime();
                    }
                    else
                        //阻塞,獲取並移除表示下一個已完成任務的 Future
                        f = ecs.take();
                }
                //阻塞隊列如果有結果
                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> 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) {
                //FutureTask底層封裝
                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);
        }
    }

 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 {
            //所有回調任務封裝成Task,且保存到集合
            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()) {
                    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);
        }
    }

總結

底層使用FutureTask
invokeAny使用ExecutorCompletionService阻塞隊列獲取結果

ThreadPoolExecutor

在這裏插入圖片描述

成員變量以及方法

 //保存線程數量和線程池的狀態,初始CTL=111 0(32-3個0)
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    private static final int COUNT_BITS = Integer.SIZE - 3;
    //線程池最大1^29-1
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    // runState is stored in the high-order bits
    //5種運行狀態,分別用高3位保存運行狀態
    // 接收新任務,並執行隊列中的任務
    private static final int RUNNING    = -1 << COUNT_BITS;
    // 不接收新任務,但是執行隊列中的任務
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    // 不接收新任務,不執行隊列中的任務,中斷正在執行中的任務
    private static final int STOP       =  1 << COUNT_BITS;
    //所有的任務都已結束,線程數量爲 0,處於該狀態的線程池即將調用 terminated()方法
    private static final int TIDYING    =  2 << COUNT_BITS;
    // terminated()方法執行完成
    private static final int TERMINATED =  3 << COUNT_BITS;

    // Packing and unpacking ctl
    //獲取高3位
    private static int runStateOf(int c)     { return c & ~CAPACITY; }
    //獲取低29位
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    private static int ctlOf(int rs, int wc) { return rs | wc; }

構造

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        //設置核心大小
        this.corePoolSize = corePoolSize;
        //設置最大線程大小
        //當添加新的執行任務,如果運行的線程少於 corePoolSize,則創建新線程來處理請求
        this.maximumPoolSize = maximumPoolSize;
        //設置工作隊列
        this.workQueue = workQueue;
        //空閒時間
        //如果池中當前有多於 corePoolSize 的線程,則這些多出的線程在空閒時間超過 keepAliveTime 時將會終止
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        //創建線程的工廠,默認Executors.defaultThreadFactory()
        this.threadFactory = threadFactory;
        //飽和策略,默認AbortPolicy()
        /*
    AbortPolicy(終止策略):默認策略,拋出RejectExecutionException
    DisCardPolicy:新提交的任務無法保存到隊列中等待執行時,拋棄該任務
    DisCardOldestPolicy:拋棄下一個將被執行的任務,嘗試重新提交新的任務(如果工作隊列是一個優先隊列,此策略會導致拋棄優先級最高的任務)
    CallerRunsPolicy:將任務回退到調用者執行,主線程在一段時間內不能提交任務,使工作者線程有時間處理完正在執行的任務,在此期間主線程不會accept,到達的請求會保存在TCP層隊列,持續過載,TCP會拋棄請求
                路徑爲:線程池-工作隊列-應用程序-TCP-客戶端
         */
        this.handler = handler;
    }



execute

 public void execute(Runnable command) {
        //空校驗
        if (command == null)
            throw new NullPointerException();

        int c = ctl.get();
        //當前工作線程個數<核心大小
        if (workerCountOf(c) < corePoolSize) {
            //添加新的工作線程,並執行
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        //核心池都在運行狀態,添加到隊列中
        if (isRunning(c) && workQueue.offer(command)) {
            //再次獲取控制狀態
            int recheck = ctl.get();
            //如果任務不處於Run狀態,則刪除任務,並拒絕任務.
            if (! isRunning(recheck) && remove(command))
                //拒絕任務
                reject(command);
            else if (workerCountOf(recheck) == 0)
                //處於運行狀態,但可使用線程爲0,則試着創建線程最大線程數新開一個新線程
                addWorker(null, false);
        }
        else if
            //核心池沒處於運行狀態或者隊列已滿,試着創建線程最大線程數新開一個新線程處理
        (!addWorker(command, false))
            //如果創建新線程失敗了,說明線程池被關閉或者線程池完全滿了,拒絕任務
            reject(command);
    }
    private boolean addWorker(Runnable firstTask, boolean core) {
        retry://goto 語句,避免死循環
        for (;;) {
            //獲取線程數量和線程池的狀態
            int c = ctl.get();
            //獲取運行狀態
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            /*
            1:線程池已經最少關閉
            2:狀態沒關閉,任務不爲空,且工作線程爲空
            同時滿足以上2條件,則直接返回false

            2種情況下允許添加新線程
            線程池處於運行狀態
            線程池處於關閉狀態,且任務爲null,且工作線程不爲空
             */
            //狀態至少SHUTDOWN,
            if (rs >= SHUTDOWN &&
                    //狀態不爲shutDown
                ! (rs == SHUTDOWN &&
                        //任務不爲空
                   firstTask == null &&
                        //工作線程爲空
                   ! workQueue.isEmpty()))
                return false;

            //自旋
            for (;;) {
                //獲取當前工作線程個數
                int wc = workerCountOf(c);
                //當前工作線程>最大上限 或根據是否開啓最大線程判斷,則返回
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                //當前工作線程+1,成功則結束
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                //cas操作失敗
                //獲取最新ctl值
                c = ctl.get();  // Re-read ctl
                //說明更改了線程池的狀態,繼續重試
                if (runStateOf(c) != rs)
                    continue retry;
                //CAS由於更改workerCount而失敗,繼續內層循環
                // else CAS failed due to workerCount change; retry inner loop
            }
        }

        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
            //創建工作線程
            w = new Worker(firstTask);
            //獲取線程
            final Thread t = w.thread;
            //線程不爲空
            if (t != null) {
                //獲取main鎖
                final ReentrantLock mainLock = this.mainLock;
                //鎖
                mainLock.lock();
                try {
                    // Recheck while holding lock.
                    // Back out on ThreadFactory failure or if
                    // shut down before lock acquired.
                    //獲取最新運行狀態
                    int rs = runStateOf(ctl.get());

                    //如果處於運行狀態,或者處於關閉狀態且任務爲null
                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        //線程存活
                        if (t.isAlive()) // precheck that t is startable
                            //線程尚未啓動,就處於存活狀態,則異常
                            throw new IllegalThreadStateException();
                        //添加到workers集合
                        workers.add(w);
                        //獲取當前工作線程大小
                        int s = workers.size();
                        //超過largestPoolSize
                        if (s > largestPoolSize)
                            //重新設置largestPoolSize
                            largestPoolSize = s;
                        //標記正常處理
                        workerAdded = true;
                    }
                } finally {
                    //釋放鎖
                    mainLock.unlock();
                }
                //正常添加
                if (workerAdded) {
                    //執行
                    t.start();
                    //標記正常啓動
                    workerStarted = true;
                }
            }
        } finally {
            //如果沒正常啓動
            if (! workerStarted)
                //異常處理,包括刪除添加的工作線程,工作線程個數-1等
                addWorkerFailed(w);
        }
        return workerStarted;
    }

  private void addWorkerFailed(Worker w) {
        //獲取重入鎖
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            if (w != null)
                //移除當前工作線程
                workers.remove(w);
            //CAS當前工作線程數量-1
            decrementWorkerCount();
            //終止線程池
            tryTerminate();
        } finally {
            mainLock.unlock();
        }
    }

    private void decrementWorkerCount() {
        do {} while (! compareAndDecrementWorkerCount(ctl.get()));
    }

tryTerminate

final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            /*處於運行狀態,或者
             *線程池狀態>=TIDYING
             *線程池=SHUTDOWN並且workQueue不爲空
             *直接return,不能終止
             */
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
                return;
            //工作線程個數>0
            if (workerCountOf(c) != 0) { // Eligible to terminate
                //中斷工作線程
                interruptIdleWorkers(ONLY_ONE);
                return;
            }

            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                //CAS設置線程池狀態爲TIDYING
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        terminated();
                    } finally {
                        //設置線程池的狀態爲TERMINATED
                        ctl.set(ctlOf(TERMINATED, 0));
                        //發送釋放信號給在termination條件上等待的線程
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                //釋放鎖
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

interruptIdleWorkers

 private void interruptIdleWorkers(boolean onlyOne) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            //遍歷工作線程
            for (Worker w : workers) {
                Thread t = w.thread;
                //當前線程沒有中斷,且嘗試獲取鎖成功
                if (!t.isInterrupted() && w.tryLock()) {
                    try {
                        //中斷
                        t.interrupt();
                    } catch (SecurityException ignore) {
                    } finally {
                        w.unlock();
                    }
                }
                //最多中斷一個線程
                if (onlyOne)
                    break;
            }
        } finally {
            mainLock.unlock();
        }
    }

run

  private boolean addWorker(Runnable firstTask, boolean core) {
//  ...
            w = new Worker(firstTask);
//...
//這裏調用的Worker.run
                    t.start();
//...
}
  Worker(Runnable firstTask) {
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }

        /** Delegates main run loop to outer runWorker  */
        public void run() {
            runWorker(this);
        }
 final void runWorker(Worker w) {
        //獲取當前線程
        Thread wt = Thread.currentThread();
        //獲取任務
        Runnable task = w.firstTask;
        //提前釋放
        w.firstTask = null;
        /*
         *unlock方法會調用AQS的release方法
         *release方法會調用具體實現類也就是Worker的tryRelease方法
         *也就是將AQS狀態置爲0,允許中斷
         * interruptIfStarted()中只有 state>=0 才允許調用中斷A
         */
        w.unlock(); // allow interrupts
        //標記是否正常執行完
        boolean completedAbruptly = true;
        try {
            //如果task不爲null,或者獲取任務不爲null,則進入循環
            //線程複用
            while (task != null || (task = getTask()) != null) {
                //不是爲了防止併發執行任務,爲了在 shutdown()時不終止正在運行的 worker
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted.  This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt
                //如果當前線程池狀態>=stop或者
                if ((runStateAtLeast(ctl.get(), STOP) ||
                // 當前線程是否被中斷(檢查中斷標誌),返回一個boolean並清除中斷狀態,第二次再調用時中斷狀態已經被清除,將返回一個false。
                     (Thread.interrupted() &&
                             //且當前線程池>=stop狀態
                      runStateAtLeast(ctl.get(), STOP))) &&
                        //測試此線程是否被中斷 ,不清除中斷狀態。
                    !wt.isInterrupted())
                    //中斷當前線程
                    wt.interrupt();
                try {
                    //鉤子方法,子類實現
                    beforeExecute(wt, task);
                    Throwable thrown = null;
                    try {
                        //執行
                        task.run();
                    } catch (RuntimeException x) {
                        thrown = x; throw x;
                    } catch (Error x) {
                        thrown = x; throw x;
                    } catch (Throwable x) {
                        thrown = x; throw new Error(x);
                    } finally {
                        //鉤子方法,子類實現
                        afterExecute(task, thrown);
                    }
                } finally {
                    //清除當前任務,下次則執行getTask獲取最新任務
                    task = null;
                    //記錄當前線程完成任務個數
                    w.completedTasks++;
                    w.unlock();
                }
            }
            //標記正常完成
            completedAbruptly = false;
        } finally {
            //後置處理
            processWorkerExit(w, completedAbruptly);
        }
    }
    private Runnable getTask() {
        //標誌是否獲取任務超時
        boolean timedOut = false; // Did the last poll() time out?

        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            //如果線程池狀態>=SHUTDOWN,且workQueue爲空
            // >=STOP,shutdownNow()會導致變成 STOP(此時不用考慮 workQueue的情況)
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                //CAS 當前線程數-1
                decrementWorkerCount();
                //當前線程會退出執行
                return null;
            }

            int wc = workerCountOf(c);

            // Are workers subject to culling?
            //判斷核心線程是否允許進行超時,默認不允許
            //當前線程數是否>核心線程數,對於超過核心線程的線程進行超時控制
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

            //超過最大線程數,只有2種設置最大線程數,構造+setMaximumPoolSize.
            // 當構造設置大小後,按照正常的順序,不會超過線程數,也就是說,這裏可能執行了setMaximumPoolSize,在CPU時鐘週期時,獲取的時之前的舊值
            // 或超時
            if ((wc > maximumPoolSize || (timed && timedOut))
                    //當前線程個數>1,且工作隊列爲空
                && (wc > 1 || workQueue.isEmpty())) {
                //當前線程數-1,成功返回null,結束當前線程執行任務
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;
            }

            try {
                //如果設置了超時,則阻塞獲取,否則直接獲取
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                    return r;
                //r爲null,說明超時,下次自旋迴收
                timedOut = true;
            } catch (InterruptedException retry) {
                //出現中斷,設置超時爲false,並循環重試
                timedOut = false;
            }
        }
    }
 private void processWorkerExit(Worker w, boolean completedAbruptly) {
        //沒正常執行成功,正常執行成功,則不需要因爲getTask執行了-1操作
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            //CAS 當前線程數量-1
            decrementWorkerCount();

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            //統計所有線程執行成功次數
            completedTaskCount += w.completedTasks;
            //刪除當前工作線程
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }

        //終止線程池
        tryTerminate();

        int c = ctl.get();
        //如果是否<stop,也就是SHUTDOWN和RUNNING狀態
        if (runStateLessThan(c, STOP)) {
            //是否正常執行成功
            if (!completedAbruptly) {
                //是否允許核心線程超時
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                //允許核心線程超時,且隊列不爲空,設置最少存活一個線程處理任務
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                //當前線程個數>1,則直接返回
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            //試着創建線程最大線程數新開一個新線程
            addWorker(null, false);
        }
    }

shutdown

  public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            //設置線程池狀態
            advanceRunState(SHUTDOWN);
            //中斷所有線程
            interruptIdleWorkers();
            //鉤子方法,子類實現
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        //終止線程池
        tryTerminate();
    }
    private void advanceRunState(int targetState) {
        for (;;) {
            int c = ctl.get();
            //c是否>=targetState狀態
            if (runStateAtLeast(c, targetState) ||
                    //設置成目標狀態
                ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
                break;
        }
    }

    private void interruptIdleWorkers() {
        //中斷所有線程
        //onlyOne
        //true表示只中斷一個
        //false:中斷所有
        interruptIdleWorkers(false);
    }

shutdownNow

 public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            //設置狀態爲stop
            advanceRunState(STOP);
            //中斷所有線程
            interruptWorkers();
            //獲取所有尚未執行任務
            tasks = drainQueue();
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
        return tasks;
    }


    private void interruptWorkers() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers)
                w.interruptIfStarted();
        } finally {
            mainLock.unlock();
        }
    }
 void interruptIfStarted() {
            Thread t;
            //允許中斷且當前線程不爲null,且測試是否已經中斷
            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
                try {
                    //中斷
                    t.interrupt();
                } catch (SecurityException ignore) {
                }
            }
        }
    private List<Runnable> drainQueue() {
        BlockingQueue<Runnable> q = workQueue;
        ArrayList<Runnable> taskList = new ArrayList<Runnable>();
        //移除此隊列中所有可用的元素,並將它們添加到給定 collection 中。
        q.drainTo(taskList);
        if (!q.isEmpty()) {
            for (Runnable r : q.toArray(new Runnable[0])) {
                if (q.remove(r))
                    //添加
                    taskList.add(r);
            }
        }
        return taskList;
    }

總結

使用Worker#lock和unlock分別控制是否能夠中斷.
在這裏插入圖片描述
在這裏插入圖片描述
執行shutdown的時候,會中斷所有空閒線程,繁忙的線程則不處理
shutdownNow中斷所有可以標記了unlock的線程,且返回尚未執行的所有任務
每個線程和任務綁定使用,當任務執行完成後,線程複用.
在這裏插入圖片描述

ScheduledThreadPoolExecutor

//todo

Thread

構造

  private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

        //線程名,默認"Thread-" + nextThreadNum()
        this.name = name;

        //獲取當前線程
        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        //線程組爲空
        if (g == null) {
            /* Determine if it's an applet or not */

            /* If there is a security manager, ask the security manager
               what to do. */
            if (security != null) {
                g = security.getThreadGroup();
            }

            /* If the security doesn't have a strong opinion of the matter
               use the parent thread group. */
            if (g == null) {
                //默認繼承父線程線程組
                g = parent.getThreadGroup();
            }
        }

        /* checkAccess regardless of whether or not threadgroup is
           explicitly passed in. */
        g.checkAccess();

        /*
         * Do we have the required permissions?
         */
        if (security != null) {
            if (isCCLOverridden(getClass())) {
                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
            }
        }

        g.addUnstarted();

        this.group = g;
        //設置是否爲守護線程,繼承調用線程的主線程,main默認是false
        this.daemon = parent.isDaemon();
        //默認5
        this.priority = parent.getPriority();
        if (security == null || isCCLOverridden(parent.getClass()))
            this.contextClassLoader = parent.getContextClassLoader();
        else
            this.contextClassLoader = parent.contextClassLoader;
        this.inheritedAccessControlContext =
                acc != null ? acc : AccessController.getContext();
        this.target = target;
        setPriority(priority);
        if (inheritThreadLocals && parent.inheritableThreadLocals != null)
            //創建線程共享變量副本
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
        //設置棧大小,如果未指定大小,將在jvm 初始化參數中聲明:Xss參數進行指定*/
        this.stackSize = stackSize;

        /* Set thread ID */
        //設置線程id
        tid = nextThreadID();
    }

start

  public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        //當前線程狀態
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        //當前線程加入線程組
        group.add(this);

        boolean started = false;
        try {
            //啓動
            start0();
            //標記正常結束
            started = true;
        } finally {
            try {
                if (!started) {
                   //線程啓動失敗,從線程組裏面移除該線程
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

interrupt

    public void interrupt() {
        //如果不是當前線程
        if (this != Thread.currentThread())
            //判斷當前線程是否允許修改其他線程
            checkAccess();

        //中斷
        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                //設置中斷標識位
                interrupt0();           // Just to set the interrupt flag
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }

join

 public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        //等待該線程終止的時間最長爲 millis 毫秒。
        if (millis == 0) {
            //測試線程是否處於活動狀態。如果線程已經啓動且尚未終止,則爲活動狀態。
            while (isAlive()) {
                wait(0);
            }
        } else {
            //指定了超時時間
            while (isAlive()) {
                long delay = millis - now;
                //超時,結束
                if (delay <= 0) {
                    break;
                }
                //等待阻塞
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

在這裏插入圖片描述

State

/* NEW:初始狀態,線程被構建,還未調用start()方法;
    RUNNABLE:運行狀態,在java多線程模型中,就緒和運行都是運行狀態;
    BLOCKED:阻塞狀態;
    WAITING:等待狀態,比如中斷,需要其他的線程來喚醒;
    TIME_WAITING:超時等待,可以在指定的時間內自行返回;
    TERMINATED:終止狀態,線程執行完畢。*/
    public enum State {}

run

    public void run() {
        if (target != null) {
            target.run();
        }
    }

總結

thread很多方法算是底層調用的了,
設置優先級調用,取決於操作系統

ThreadFactory

在這裏插入圖片描述
基本上都是當做內部類使用,隨便看一個實現即可
java.util.concurrent.Executors.DefaultThreadFactory

DefaultThreadFactory

    static class DefaultThreadFactory implements ThreadFactory {
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        DefaultThreadFactory() {
            SecurityManager s = System.getSecurityManager();
            //默認繼承父類線程組
            group = (s != null) ? s.getThreadGroup() :
                                  Thread.currentThread().getThreadGroup();

            //pool-自增1開始-thread-
            namePrefix = "pool-" +
                          poolNumber.getAndIncrement() +
                         "-thread-";
        }

        public Thread newThread(Runnable r) {
            //pool-1-thread-1
            Thread t = new Thread(group, r,
                                  namePrefix + threadNumber.getAndIncrement(),
                                  0);
            //是否是守護線程
            if (t.isDaemon())
                //如果是守護線程,則設置成普通線程
                t.setDaemon(false);
            //
            //設置優先級,默認5
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }

Executors

 public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
        //線程最大設置Integer.MAX,基本大小=0,超時設置1分鐘
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>(),
                                      threadFactory);
    }

    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
  //創建一個可重用固定線程數的線程池,以共享的無界隊列方式來運行這些線程
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>(),
                                      threadFactory);
    }

    public static ScheduledExecutorService newScheduledThreadPool(
            int corePoolSize, ThreadFactory threadFactory) {
        //創建一個線程池,它可安排在給定延遲後運行命令或者定期地執行。
        return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
    }

   public static ExecutorService newSingleThreadExecutor() {
        //創建一個使用單個 worker 線程的 Executor,以無界隊列方式來運行該線程。
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

ExecutorCompletionService

阻塞獲取結果

構造

    public ExecutorCompletionService(Executor executor) {
        if (executor == null)
            throw new NullPointerException();
        this.executor = executor;
        this.aes = (executor instanceof AbstractExecutorService) ?
            (AbstractExecutorService) executor : null;
        //使用LinkedBlockingQueue保存結果
        this.completionQueue = new LinkedBlockingQueue<Future<V>>();
    }


    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;
    }

submit

    public Future<V> submit(Callable<V> task) {
        if (task == null) throw new NullPointerException();
        //封裝成FutureTask
        RunnableFuture<V> f = newTaskFor(task);
        //封裝成阻塞結果的FutureTask,執行
        executor.execute(new QueueingFuture(f));
        return f;
    }
   private class QueueingFuture extends FutureTask<Void> {
        QueueingFuture(RunnableFuture<V> task) {
            super(task, null);
            this.task = task;
        }
        protected void done() {
            //實現父類,完成後添加到阻塞隊列
            completionQueue.add(task); }
        private final Future<V> task;
    }

take

    public Future<V> take() throws InterruptedException {
        //阻塞獲取結果
        return completionQueue.take();
    }

poll

    public Future<V> poll() {
        //直接獲取結果,沒有返回null
        return completionQueue.poll();
    }

總結

底層封裝阻塞隊列,且封裝了FutureTask,當執行結束,把Future存儲到阻塞隊列中.

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