一、線程池工作流程 1. 線程池判斷核心線程池裡的線程是否都在執行任務。如果不是,則創建一個新的工作線程來執行任務(需要獲得全局鎖)。如果核心線程池裡的線程都在執行任務,則進入下個流程。 2. 線程池判斷工作隊列是否已滿。如果工作隊列沒有滿,則將新提交的任務存儲在這個工作隊列里。如果工 ...
一、線程池工作流程
- 線程池判斷核心線程池裡的線程是否都在執行任務。如果不是,則創建一個新的工作線程來執行任務(需要獲得全局鎖)。如果核心線程池裡的線程都在執行任務,則進入下個流程。
- 線程池判斷工作隊列是否已滿。如果工作隊列沒有滿,則將新提交的任務存儲在這個工作隊列里。如果工作隊列滿了,則進入下個流程。
- 線程池判斷線程池的線程是否都處於工作狀態。如果沒有,則創建一個新的工作線程來執行任務(需要獲得全局鎖)。如果已經滿了,則交給飽和策略(例如拋出異常)來處理這個任務。
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框架的使用示意圖如下: