1. 程式人生 > >執行緒池 --------常見的四中執行緒池

執行緒池 --------常見的四中執行緒池

由於執行緒的頻繁排程,而影響效能,通過執行緒池來維護,減少執行緒的頻繁的建立和銷燬。
在Executors統一管理,看一下常見的四中執行緒池:
1.newFixedThreadPool:建立定長的執行緒池,超出定長線上程佇列中等待。

 public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

2.newCachedThreadPool:執行緒數無限大,當執行緒佇列中有空閒執行緒時會複用,否則重新建立執行緒,同時執行緒60s沒有用時,從執行緒佇列中移除。

 public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

3.newScheduledThreadPool:次執行緒池是在規定的時間進行排程。

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }

4.newSingleThreadExecutor:僅有一個執行緒在排程,且有順序的進行出隊和入隊。

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

但是他們都呼叫了ThreadPoolExecutor:看一下核心構造器裡的幾個引數
corePoolSize: 要保留在池中的執行緒數量。
maximumPoolSize:執行緒池中允許的最大執行緒數。
keepAliveTime:空閒執行緒等待的最大時間。
unit:keepAliveTime的時間單位。
workQueue:可執行的任務佇列。
threadFactory:執行建立一個新的執行緒時使用。
handler:當達到了執行緒邊界和佇列容量,執行被阻塞時使用的處理程式。

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.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

執行緒池中常用幾個方法原始碼:
看一下runState控制得幾種狀態:

RUNNING:  接受新任務並能夠對新增的任務處理。
SHUTDOWN: 不接受新任務,但能處理已在佇列中的任務。
STOP:    不接受新任務,不處理排隊的任務,並同時中斷正在進行的任務。
TIDYING:  所有任務全部中斷,同時將workerCount 置0,並將所有執行緒切換到TIDYING狀態,會執行鉤子函式terminated()。
TERMINATED: 表示執行緒池徹底終止。執行完terminated()之後,就會由 TIDYING -> TERMINATED。

執行緒池的幾種轉態轉換:
在這裡插入圖片描述

 public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();//保證了資料的原子性,不被其他執行緒干擾
        if (workerCountOf(c) < corePoolSize) {//執行的執行緒數小於corePoolSize的數量時
            if (addWorker(command, true))//新增一個新的到任務中
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {//插入任務成功且是Running狀態下
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))//移除任務成功且不是Running狀態下
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        //如果新增到任務中失敗,丟擲異常。
        else if (!addWorker(command, false))
            reject(command);
    }

這裡addWorker(Runnable firstTask, boolean core)中的兩個引數:
firstTask:新執行緒首要執行。
core:用一個布林值判斷當前執行緒數是否小於corePoolSize或maximumPoolSize。在原始碼中

wc >= (core ? corePoolSize : maximumPoolSize))

shutdown()方法:對以前的任務切換到SHUTDOWN狀態,不接受新的任務。

public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;//重入鎖
        mainLock.lock();
        try {
            checkShutdownAccess();//判斷呼叫者是否有許可權shutdown執行緒池
            advanceRunState(SHUTDOWN);//執行緒池狀態切換為SHUTDOWN
            interruptIdleWorkers();//中斷可能正在等待任務的執行緒
            onShutdown(); // SHUTDOWN轉態下的進一步清理。但是使用了ScheduledThreadPoolExecutor取消延遲的任務。
        } finally {
            mainLock.unlock();
        }
        tryTerminate();//試著終止執行緒池
    }