池化技術相比大家已經屢見不鮮了,線程池、數據庫連接池、Http 連接池等等都是對這個思想的應用。池化技術的思想主要是為了減少每次獲取資源的消耗,提高對資源的利用率。 線程池提供了一種限制和管理資源(包括執行一個任務)。 每個線程池還維護一些基本統計信息,例如已完成任務的數量。
這里借用《Java 并發編程的藝術》提到的來說一下使用線程池的好處:
- 降低資源消耗。通過重復利用已創建的線程降低線程創建和銷毀造成的消耗。
- 提高響應速度。當任務到達時,任務可以不需要的等到線程創建就能立即執行。
- 提高線程的可管理性。線程是稀缺資源,如果無限制的創建,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一的分配,調優和監控。
Executor 框架
Executor 框架是 Java5 之后引進的,在 Java 5 之后,通過 Executor 來啟動線程比使用 Thread 的 start 方法更好,除了更易管理,效率更好(用線程池實現,節約開銷)外,還有關鍵的一點:有助于避免 this 逃逸問題。
補充:this 逃逸是指在構造函數返回之前其他線程就持有該對象的引用. 調用尚未構造完全的對象的方法可能引發令人疑惑的錯誤。
Executor 框架不僅包括了線程池的管理,還提供了線程工廠、隊列以及拒絕策略等,Executor 框架讓并發編程變得更加簡單。
Executor 框架結構(主要由三大部分組成)
- 任務(Runnable /Callable) 執行任務需要實現的 Runnable 接口 或 Callable接口。Runnable 接口或 Callable 接口 實現類都可以被 ThreadPoolExecutor 或 ScheduledThreadPoolExecutor 執行。
- 任務的執行(Executor) 如下圖所示,包括任務執行機制的核心接口 Executor ,以及繼承自 Executor 接口的 ExecutorService 接口。ThreadPoolExecutor 和 ScheduledThreadPoolExecutor 這兩個關鍵類實現了 ExecutorService 接口。
這里提了很多底層的類關系,但是,實際上我們需要更多關注的是 ThreadPoolExecutor 這個類,這個類在我們實際使用線程池的過程中,使用頻率還是非常高的。
注意: 通過查看 ScheduledThreadPoolExecutor 源代碼我們發現 ScheduledThreadPoolExecutor 實際上是繼承了 ThreadPoolExecutor 并實現了 ScheduledExecutorService ,而 ScheduledExecutorService 又實現了 ExecutorService,正如我們下面給出的類關系圖顯示的一樣。
ThreadPoolExecutor 類描述:
1
2
|
//AbstractExecutorService實現了ExecutorService接口 public class ThreadPoolExecutor extends AbstractExecutorService |
ScheduledThreadPoolExecutor 類描述:
1
2
3
4
|
//ScheduledExecutorService實現了ExecutorService接口 public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService |
3) 異步計算的結果(Future) Future 接口以及 Future 接口的實現類 FutureTask 類都可以代表異步計算的結果。
當我們把 Runnable接口 或 Callable 接口 的實現類提交給 ThreadPoolExecutor 或 ScheduledThreadPoolExecutor 執行。(調用 submit() 方法時會返回一個 FutureTask 對象)
Executor 框架的使用示意圖
- 主線程首先要創建實現 Runnable 或者 Callable 接口的任務對象。
- 把創建完成的實現 Runnable/Callable接口的 對象直接交給 ExecutorService 執行: ExecutorService.execute(Runnable command))或者也可以把 Runnable 對象或Callable 對象提交給 ExecutorService 執行(ExecutorService.submit(Runnable task)或 ExecutorService.submit(Callable task))。
- 如果執行 ExecutorService.submit(…),ExecutorService 將返回一個實現Future接口的對象(我們剛剛也提到過了執行 execute()方法和 submit()方法的區別,submit()會返回一個 FutureTask 對象)。由于 FutureTask 實現了 Runnable,我們也可以創建 FutureTask,然后直接交給 ExecutorService 執行。
- 最后,主線程可以執行 FutureTask.get()方法來等待任務執行完成。主線程也可以執行 FutureTask.cancel(boolean mayInterruptIfRunning)來取消此任務的執行。
以上就是Java使用線程池的優勢有哪些的詳細內容,更多關于Java 線程池的資料請關注服務器之家其它相關文章!
原文鏈接:https://cloud.tencent.com/developer/article/1640007