前言
池化技術已經屢見不鮮了,比如數據庫連接池,大家的項目中應該也用到了線程池。池化技術的好處:降低資源的消耗,提高響應速度,提高線程的可管理性。本篇主要是和大家一起分析下線程池的架構和它的工作流程。
1、線程池架構圖
架構圖中,有三個接口,三個類,下面分別介紹下它們:
1、Executor
public interface Executor {
void execute(Runnable command);
}
Executor的接口只定義了一個方法,該方法是用來執行已提交的 Runnable 任務的對象。
2、ExecutorService
ExecutorService定義了一系列的“提交”、“關閉”、“執行”等方法,來服務於Executor,從命名上咱們也能理解爲什麼叫ExecutorService。
3、AbstractExecutorService
AbstractExecutorService抽象類爲ExecutorService中的函數接口提供了默認實現。
4、ThreadPoolExecutor
ThreadPoolExecutor這個就是我們常說的“線程池”,該類繼承了AbstractExecutorService,具體的分析會在下一篇重點分析。
5、ScheduledExecutorService
ScheduledExecutorService接口從名字上就可以看出來,它相當於提供了“延遲”、“週期”功能的ExecutorService。
6、ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor類就是提供了“延遲”、“週期”功能的ThreadPoolExecutor。
2、工作流程
- 主線程創建實現Runnable或Callable接口的任務對象。
- 主線程將任務對象交給ExecutorService的實現類(ThreadPoolExecutor或ScheduledThreadPoolExecutor對象)執行execut或者submit方法來執行。
- ExecutorService若執行execut方法,則不返回結果;若執行submit方法,則返回FutureTask對象。
- 若有返回對象,主線程則執行 FutureTask.get()方法等待任務執行完成。
3、示例
public class ThreadPoolTest {
//這裏是創建一個2個固定線程的線程池
//《阿里巴巴 Java 開發手冊》中強制不允許使用 Executors 去創建線程池
//詳細解釋會在下一篇後面給出
private static ExecutorService executorService = Executors.newFixedThreadPool(2);
public static void main(String[] args) {
for (int i=0; i<10; i++){
//創建實現Runnable接口的對象
Runnable thread = new MyRunnable();
//執行任務
executorService.execute(thread);
}
executorService.shutdown();
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
控制檯輸出:
pool-1-thread-1
pool-1-thread-1
pool-1-thread-1
pool-1-thread-1
pool-1-thread-1
pool-1-thread-1
pool-1-thread-1
pool-1-thread-1
pool-1-thread-1
pool-1-thread-2