本節學習Executors類源碼
首先看一下常用的線程池的幾種創建方式
/**
* 創建一個線程池,該線程池重用固定數量的線程,在共享的無界隊列中運行
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
/**
* 創建一個線程池,該線程池只有一個工作者線程運行在無界隊列中
*/
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
/**
* 創建一個線程池,如果需要就創建線程, 但是會重用之前已創建的可用線程
*/
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
/**
* 創建一個可定時執行任務的線程池
*/
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
下面看一下ThreadPoolExecutor類
有幾個核心的參數:
/**
* 阻塞隊列,保存任務並交給工作者線程
*/
private final BlockingQueue<Runnable> workQueue;
/**
* 重入鎖
*/
private final ReentrantLock mainLock = new ReentrantLock();
/**
* 工作者線程集合
*/
private final HashSet<Worker> workers = new HashSet<Worker>();
/**
* Wait condition to support awaitTermination
*/
private final Condition termination = mainLock.newCondition();
/**
* 跟蹤最大線程池大小
*/
private int largestPoolSize;
/**
* 已執行完成的線程個數
*/
private long completedTaskCount;
/**
* 創建線程的工廠
*/
private volatile ThreadFactory threadFactory;
/**
* 飽和策略執行者
*/
private volatile RejectedExecutionHandler handler;
/**
* 空閒工作線程的空閒時間;超過corePoolSize的線程或者allowCoreThreadTimeOut爲true的主線程使用這個作爲超時時間;
否則線程一直等待任務或關閉
*/
private volatile long keepAliveTime;
/**
* 如果爲false,核心線程會一直存活
* 如果爲true,核心線程使用keepAliveTime等待空閒工作者線程超時
*/
private volatile boolean allowCoreThreadTimeOut;
/**
* 核心線程個數
*/
private volatile int corePoolSize;
/**
* 最大線程個數
*/
private volatile int maximumPoolSize;
/**
* 默認的拒絕策略
*/
private static final RejectedExecutionHandler defaultHandler =
new AbortPolicy();
/**
* 構造函數,創建線程池
*/
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;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);//毫秒
this.threadFactory = threadFactory;
this.handler = handler;
}
下面看一下線程池執行任務的過程:
/**
* 執行任務
*/
public void execute(Runnable command) {
if (command == null)//如果任務爲空,拋異常
throw new NullPointerException();
/*
* 1. 如果工作者線程個數少於corePoolSize,添加一個工作者線程
* 2. 否則,如果線程池處於運行狀態則嘗試插入工作隊列中,如果插入成功,再次檢查線程池狀態,如果非運行,則隊列中移除任務,且拒絕該任務,如果工作者線程爲0,則添加工作者線程
* 3. 如果不能插入工作隊列中,則嘗試創建新的線程,如果失敗,則拒絕任務。
*/
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();//重新檢查,如果線程數超過最大,則拒絕任務,從隊列中移除任務
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
/**
* 創建新的線程
*/
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);//獲取工作線程個數
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))//如果超過最大或者核心線程數,則返回false
return false;
if (compareAndIncrementWorkerCount(c))//線程個數+1
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// 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) {
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());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);//添加到工作集合中
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;//設置最大線程數
workerAdded = true;
}
} finally {
mainLock.unlock();//釋放鎖
}
if (workerAdded) {
t.start();//執行任務
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);//任務啓動失敗,則從任務隊列中移除該任務,ctl減一
}
return workerStarted;
}
/**
*拒絕任務
*/
final void reject(Runnable command) {
handler.rejectedExecution(command, this);
}
默認使用的是AbortPolicy,直接拋出RejectedExecutionException異常
還有三種策略:
1.CallerRunsPolicy:如果線程池非中斷狀態,則直接在調用拒絕的線程上執行該任務,否則丟棄任務。
2.DiscardOldestPolicy:如果線程池在非中斷狀態,則從工作隊列中移除最近的任務,且執行新的任務,否則丟棄任務
3. DiscardPolicy : 丟棄任務,什麼也不做。
下面看一下任務的執行
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {//如果task爲空,則從隊列中獲取
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
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
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 {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);//從workers移除
}
}