多執行緒編程學習十(執行緒池原理).
- 2019 年 10 月 6 日
- 筆記
一、執行緒池工作流程

- 執行緒池判斷核心執行緒池裡的執行緒是否都在執行任務。如果不是,則創建一個新的工作執行緒來執行任務(需要獲得全局鎖)。如果核心執行緒池裡的執行緒都在執行任務,則進入下個流程。
- 執行緒池判斷工作隊列是否已滿。如果工作隊列沒有滿,則將新提交的任務存儲在這個工作隊列里。如果工作隊列滿了,則進入下個流程。
- 執行緒池判斷執行緒池的執行緒是否都處於工作狀態。如果沒有,則創建一個新的工作執行緒來執行任務(需要獲得全局鎖)。如果已經滿了,則交給飽和策略(例如拋出異常)來處理這個任務。
tips:這樣的設計方案,可以避免頻繁的執行緒創建,大部分的工作任務都會停留在第二步。
二、Executor 框架
在 Java 中,執行緒池的知識是要從 Executor 框架展開。Executor 框架主要由三部分組成:
1. 任務
包括 Runnable 介面或 Callable 介面。Runnable 介面無返回值,Callable 有返回值。
// Runnable 和 Callable 都可以直接被 ThreadPoolExecutor 和 ScheduledThreadPoolExecutor 執行 Runnable runnable = () -> System.out.println(123); // Executors 可以將 Runnable 轉化成 Callable Callable<Object> callable = Executors.callable(runnable); Callable<String> success = Executors.callable(runnable, "success");
2. 任務的執行
包括任務執行機制的核心介面 Executor、繼承自 Executor 的 ExecutorService 介面以及實現 ExecutorService 的 ThreadPoolExecutor 和 ScheduledThreadPoolExecutor。
ThreadPoolExecutor 是執行緒池的核心實現類,用來執行被提交的任務。其中 ThreadPoolExecutor 的原理就是上面介紹的執行緒池工作流程。
ScheduledThreadPoolExecutor 繼承自 ThreadPoolExecutor ,可以在給定的延遲後執行任務,或者定期執行任務。
Executors 是創建 ThreadPoolExecutor 和 ScheduledThreadPoolExecutor 的工廠類。
static ExecutorService executorService = Executors.newFixedThreadPool(5);
3. 非同步計算的結果
包括 Future 介面以及實現 Future 的 FutureTask 類。
// 執行 Runnable executorService.execute(runnable); // 執行 Callable Future<Object> submit = executorService.submit(callable); // Future 的 get 方法會阻塞執行緒直到完成 System.out.println(submit.get()); Future<String> future = executorService.submit(success); System.out.println(future.get());
Executor 執行緒池的使用大抵如下,首先,我們需要創建 Runnable 或者 Callable 任務。然後通過 ThreadPoolExecutor.execute() 或者 ThreadPoolExecutor.submit() 把任務交給 ThreadPoolExecutor 容器執行。由 submit 提交的任務會返回 Future,表示執行緒執行的結果,其中 Future 的 get 方法會阻塞執行緒直到完成。
Executor框架的使用示意圖如下:
