執行緒池 --------常見的四中執行緒池
由於執行緒的頻繁排程,而影響效能,通過執行緒池來維護,減少執行緒的頻繁的建立和銷燬。
在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();//試著終止執行緒池
}