下面若是有貼出源碼,對應的源碼是JDK8java
主要的源碼類源碼分析
java.util.concurrent.ThreadPoolExecutor、
java.util.concurrent.ThreadPoolExecutor.Worker
java.util.concurrent.AbstractExecutorServicethis
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) 複製代碼
內部有重要的成員變量ctl,類型是AtomicInteger,低29位表示線程池中線程數,經過高3位表示線程池的運行狀態spa
COUNT_BITS的值是29線程
execute --> addWorker --> Thread.start --> (Thread.run) --> runTask --> getTaskcode
3.1execute(Runnable command)orm
大體分三個步驟cdn
3.2 addWorker(Runnable firstTask, boolean core)對象
3.3 runWorker(Worker w)blog
經過循環調用getTask()獲取要執行的任務task
beforeExecute
task.run()
afterExecute
3.4 getTask()
源碼以下:
private Runnable getTask() {
Boolean timedOut = false;
// 是否最後的 poll() 超時了?
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
Boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
// worker是否須要被淘汰
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
// 這裏會讓線程的數量記錄減,後面的return null,會致使runWorker沒有獲取到數據而讓run()方法走到盡頭,最終當前線程結束
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
// 若是須要回收一部分線程,那麼超時時間keepAliveTime後拿不到就數據就繼續循環調用,就能夠在下一次循環的時候進行線程結束回收了;不然一直阻塞下去
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
}
catch (InterruptedException retry) {
timedOut = false;
}
}
}
複製代碼
源碼以下:
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
複製代碼
代碼比較簡單,把任務封裝成一個既實現Runnable, 也實現Future<v style="margin: 0px; padding: 0px;">
的接口,這個時候就能夠調用execute()
進行實現了</v>