【JDK源碼分析系列】ThreadPoolExecutor 源碼解析 -- ThreadPoolExecutor 的類結構
【1】線程池整體執行流程圖示
線程池相關詳細介紹參見 【JAVA併發編程系列】併發框架 -- Executor 框架(線程池)
【2】ThreadPoolExecutor 的類結構
【2.1】Executor
// Executor:定義 execute 方法來執行任務,入參是 Runnable,無出參
public interface Executor {
void execute(Runnable command);
}
【2.2】ExecutorService
public interface ExecutorService extends Executor {
// 關閉,不會接受新的任務,也不會等待未完成的任務
// 如果需要等待未完成的任務,可以使用 awaitTermination 方法
void shutdown();
// 試圖關閉所有正在執行的任務,返回等待執行的任務列表
List<Runnable> shutdownNow();
// 判斷 executor 是否關閉了,true 已關閉
boolean isShutdown();
// 所有的任務是否都已經終止,是的話,返回 true
boolean isTerminated();
// 在超時時間內阻塞,等待所有的任務執行完成
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
// 提交有返回值的任務,使用 get 方法可以阻塞等待任務的結果返回
<T> Future<T> submit(Callable<T> task);
// 提交有返回值的任務,使用 get 方法可以阻塞等待任務的結果返回
<T> Future<T> submit(Runnable task, T result);
// 提交沒有返回值的任務
// 任務執行完成之後,返回 null 值
Future<?> submit(Runnable task);
// 給定任務集合,返回已經執行完成的 Future 集合,每個返回的 Future 都是 isDone = true 的狀態
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
// 給定任務集合,返回已經執行完成的 Future 集合,每個返回的 Future 都是 isDone = true 的狀態
// 該方法具有 TimeOut 判斷
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException;
// 給定任務中有一個執行成功就返回,如果拋異常,其餘未完成的任務將被取消
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException;
// 給定任務中有一個執行成功就返回,如果拋異常,其餘未完成的任務將被取消
// 該方法具有 TimeOut 判斷
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
【2.3】AbstractExecutorService
AbstractExecutorService 是一個抽象類,封裝了 Executor 的很多通用功能。
【2.3.1】AbstractExecutorService -- newTaskFor
// 把 Runnable 轉化成 RunnableFuture
// RunnableFuture 是一個接口,實現了 Runnable 和 Future
// FutureTask 是 RunnableFuture 的實現類,主要是對任務進行各種管理
// Runnable + Future => RunnableFuture => FutureTask
// FutureTask 其本身就是一個任務,而且具備對任務管理的功能,
// 比如可以通過 get 方法拿到任務的執行結果
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
// 把 Runnable 轉化成 RunnableFuture
// RunnableFuture 是一個接口,實現了 Runnable 和 Future
// FutureTask 是 RunnableFuture 的實現類,主要是對任務進行各種管理
// Runnable + Future => RunnableFuture => FutureTask
// FutureTask 其本身就是一個任務,而且具備對任務管理的功能,
// 比如可以通過 get 方法拿到任務的執行結果
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
【2.3.2】AbstractExecutorService -- submit
// submit 方法是使用線程池時提交任務的方法,支持 Runable 和 Callable 兩種任務的提交,
// 方法中 execute 方法是其子類 ThreadPoolExecutor 實現的,不管是哪種任務入參,
// execute 方法最終執行的任務都是 FutureTask
//
// 提交無返回值的 Runnable 任務
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
// ftask 其實是 FutureTask
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
// 提交有返回值的 Runnable 任務,
// task 是 Runnable 類型在 FutureTask 中進行向 Callable 的轉換
public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
// 提交 Callable 任務
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
【2.3.3】AbstractExecutorService -- invokeAny
// 給定任務中有一個執行成功就返回,
// 一旦invokeAny方法正常返回或者拋出異常,那些沒有完成的任務將被取消
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;
}
}
// 給定任務中有一個執行成功就返回,
// 一旦invokeAny方法正常返回或者拋出異常,那些沒有完成的任務將被取消
// 帶有超時處理
public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
// 具體執行方法
return doInvokeAny(tasks, true, unit.toNanos(timeout));
}
// invokeAny 具體實現方法
private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
boolean timed, long nanos)
throws InterruptedException, ExecutionException, TimeoutException {
if (tasks == null)
throw new NullPointerException();
// 獲取 task 的數量
int ntasks = tasks.size();
if (ntasks == 0)
throw new IllegalArgumentException();
// ArrayList 緩存 Future 結構變量
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
// ExecutorCompletionService 類
// 內部屬性
// private final Executor executor;
// private final AbstractExecutorService aes;
// private final BlockingQueue<Future<V>> completionQueue;
//
// 構造函數
// public ExecutorCompletionService(Executor executor) {
// if (executor == null)
// throw new NullPointerException();
// this.executor = executor;
// this.aes = (executor instanceof AbstractExecutorService) ?
// (AbstractExecutorService) executor : null;
// this.completionQueue = new LinkedBlockingQueue<Future<V>>();
// }
ExecutorCompletionService<T> ecs =
new ExecutorCompletionService<T>(this);
try {
// Record exceptions so that if we fail to obtain any
// result, we can throw the last exception we got.
ExecutionException ee = null;
final long deadline = timed ? System.nanoTime() + nanos : 0L;
Iterator<? extends Callable<T>> it = tasks.iterator();
// Start one task for sure; the rest incrementally
//
// 此處提交一個可排隊的 FutureTask
// public Future<V> submit(Callable<V> task) {
// if (task == null) throw new NullPointerException();
// RunnableFuture<V> f = newTaskFor(task);
// executor.execute(new QueueingFuture(f));
// return f;
// }
//
// private class QueueingFuture extends FutureTask<Void> {
// QueueingFuture(RunnableFuture<V> task) {
// super(task, null);
// this.task = task;
// }
// // 實現了 FutureTask 中的 done 方法, 將 FutureTask 添加到阻塞隊列中
// // 在 FutureTask 的 finishCompletion() 調用
// protected void done() { completionQueue.add(task); }
// private final Future<V> task;
// }
futures.add(ecs.submit(it.next()));
--ntasks;
int active = 1;
for (;;) {
// 嘗試從阻塞隊列中獲取 FutureTask
// poll(time):
// 取走BlockingQueue裏排在首位的對象,若不能立即取出,
// 則可以等time參數規定的時間,取不到時返回null
Future<T> f = ecs.poll();
if (f == null) {
if (ntasks > 0) {
--ntasks;
futures.add(ecs.submit(it.next()));
++active;
}
else if (active == 0)
break;
else if (timed) {
// 嘗試從阻塞隊列中獲取 FutureTask
// poll(time):
// 取走BlockingQueue裏排在首位的對象,若不能立即取出,
// 則可以等time參數規定的時間,取不到時返回null
f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
if (f == null)
throw new TimeoutException();
nanos = deadline - System.nanoTime();
}
else
// take():取走BlockingQueue裏排在首位的對象,若BlockingQueue爲空,
// 阻塞i進入等待狀態直到Blocking有新的對象被加入爲止
f = ecs.take();
}
if (f != null) {
--active;
try {
// 返回 FutureTask 中的結果
// 1.try 或 catch 中都有 return語句,並且有 finally,
// 最終先執行 finally,再執行 try 或 catch中的 return語句
// 2.try 或 catch 中都有 return語句,並且有 finally,
// 而且 finally中 有return語句 的話,最終先執行 finally,
// 然後執行 finally中 有return語句,並不會執行 try 或 catch 中return語句
// 3.try 或 catch 中都有 return語句,並且有 finally,而且 finally中 對try 或 catch 中的
// return語句所返回的基本類型變量/引用類型變量 進行了重新賦值,
// 即使如此,也只會返回 try 或 catch 中的return語句所返回的基本類型變量/引用類型變量的值,
// finally中的修改try 或 catch 中的返回值操作並不會生效
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++)
//移除 ArrayList 中的 FutureTask
futures.get(i).cancel(true);
}
}
【2.3.4】AbstractExecutorService -- invokeAll
// 給定任務集合,返回已經執行完成的 Future 集合,每個返回的 Future 都是 isDone = true 的狀態
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
if (tasks == null)
throw new NullPointerException();
//新建一個 tasks.size() 的 ArrayList 用於緩存 FutureTask
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
//遍歷 tasks 將其中的 FutureTask 加入到 futures
for (Callable<T> t : tasks) {
RunnableFuture<T> f = newTaskFor(t);
futures.add(f);
//執行 FutureTask
execute(f);
}
//遍歷 futures 嘗試獲取執行結果
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;
//返回所有 FutureTask 的執行結果
return futures;
} finally {
if (!done)
//該 if 判斷成立表示出現了異常情況需要取消 FutureTask
for (int i = 0, size = futures.size(); i < size; i++)
futures.get(i).cancel(true);
}
}
// 給定任務集合,返回已經執行完成的 Future 集合,每個返回的 Future 都是 isDone = true 的狀態
// 帶有超時處理 timeout 爲所有任務執行完畢的截止時間限制
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException {
if (tasks == null)
throw new NullPointerException();
//TimeOut 記錄變量
long nanos = unit.toNanos(timeout);
//新建一個 tasks.size() 的 ArrayList 用於緩存 FutureTask
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
//遍歷 tasks 將其中的 FutureTask 加入到 futures
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.
// 遍歷執行 futures 中的 FutureTask
for (int i = 0; i < size; i++) {
execute((Runnable)futures.get(i));
nanos = deadline - System.nanoTime();
if (nanos <= 0L)
// 若超時則之間返回 futures 此時 done 爲 false
// 則會在 finally 代碼塊中取消 FutureTask 任務
return futures;
}
for (int i = 0; i < size; i++) {
Future<T> f = futures.get(i);
if (!f.isDone()) {
if (nanos <= 0L)
// 超時則返回 futures
return futures;
try {
// 帶超時的獲取執行結果
f.get(nanos, TimeUnit.NANOSECONDS);
} catch (CancellationException ignore) {
} catch (ExecutionException ignore) {
} catch (TimeoutException toe) {
// 若超時則之間返回 futures 此時 done 爲 false
// 則會在 finally 代碼塊中取消 FutureTask 任務
return futures;
}
nanos = deadline - System.nanoTime();
}
}
done = true;
// 若超時則之間返回 futures 此時 done 爲 true
// 任務不會被取消返回正常執行的結果
return futures;
} finally {
if (!done)
for (int i = 0, size = futures.size(); i < size; i++)
futures.get(i).cancel(true);
}
}
參考致謝
本博客爲博主的學習實踐總結,並參考了衆多博主的博文,在此表示感謝,博主若有不足之處,請批評指正。
【2】Java併發編程的藝術