Executor框架、ThreadPoolExecutor、3种常见的线程池
參考:https://blog.csdn.net/javazejian/article/details/50890554
1. Executor框架
為什么需要線程池?
在java中,使用線程來執行異步任務時,線程的創建和銷毀需要一定的開銷,如果我們為每一個任務創建一個新的線程來執行的話,那么這些線程的創建與銷毀將消耗大量的計算資源。
同時為每一個任務創建一個新線程來執行,這樣的方式可能會使處于高負荷狀態的應用最終崩潰。
所以線程池的出現為解決這個問題帶來曙光。
我們將在線程池中創建若干條線程,當有任務需要執行時就從該線程池中獲取一條線程來執行任務,如果一時間任務過多,超出線程池的線程數量,那么后面的線程任務就進入一個等待隊列進行等待,直到線程池有線程處于空閑時才從等待隊列獲取要執行的任務進行處理,以此循環.....這樣就大大減少了線程創建和銷毀的開銷,也會緩解我們的應用處于超負荷時的情況。
1.1 Executor框架的兩級調度模型
在java線程啟動時會創建一個本地操作系統線程,當該java線程終止時,這個操作系統線程也會被回收。
而每一個java線程都會被一對一映射為本地操作系統的線程,操作系統會調度所有的線程并將它們分別給可用的CPU。
而所謂的映射方式是這樣實現的:
- 在上層,java多線程程序通過把應用分為若干個任務,然后使用用戶級的調度器(Executor框架)將這些任務映射為固定數量的線程;
- 在底層,操作系統內核將這些線程映射到硬件處理器上。這樣種兩級調度模型如下圖所示:
從圖中我們可以看出,應用程序通過Executor框架控制上層的調度,而下層的調度由操作系統內核控制,下層的調度不受應用程序的控制。
1.2 Executor框架的結構
Executor框架的結構主要包括3個部分
這些類間的關系的UML圖:
- Extecutor是一個接口,它是Executor框架的基礎,它將任務的提交與任務的執行分離開來。
- ThreadPoolExecutor是線程池的核心實現類,用來執行被提交的任務。
- ScheduledThreadPoolExecutor是一個實現類,可以在給定的延遲后運行命令,或者定期執行命令。
- ScheduledThreadPoolExecutor比Timer更靈活,功能更強大。
- Future接口和實現Future接口的FutureTask類,代表異步計算的結果。
- Runnable接口和Callable接口的實現類,都可以被ThreadPoolExecutor或者ScheduledThreadPoolExecutor執行。區別就是Runnable無法返回執行結果,而Callable可以返回執行結果。
- Executor 和 ExectorService 這兩個接口的主要區別:
- ExectorService 接口繼承了Executor 接口,是它的子接口;
- Executor 接口定義了execute()方法用來接收一個Runnable接口的對象,而ExecutorService接口中的submit()方法可以接受Runnable和Callable接口的對象;
- Executor 中的execute()方法不返回任何結果,ExecutorService的submit()方法可以通過一個Future對象返回運算結果;
- ExecutorService允許客戶端提交一個任務,并且還提供用來控制線程池的方法,比如:調用shutDown()方法終止線程池
它們間的執行關系:
分析說明:
到此Executor框架的主要體系結構我們都介紹完了,我們對此有了大概了解后,下面我們就重點聊聊兩個主要的線程池實現類。
2.ThreadPoolExecutor
3. 3種常見的線程池
它們都直接或者間接地通過配置ThreadPoolExecutor來實現自己的功能特性,這個3種線程池分別是FixedThreadPool,CachedThreadPool,ScheduledThreadPool以及SingleThreadExecutor。
?
總結
以上是生活随笔為你收集整理的Executor框架、ThreadPoolExecutor、3种常见的线程池的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: float 与 double、隐式类型转
- 下一篇: 线程的状态转换、sleep()、wait