多線程知識梳理(5) 線程池四部曲之 Executor 框架

1、Executor 框架的調度模型

1.1 目的

在平時的開發中,咱們常常須要將一些耗時的任務放到異步線程當中進行處理,而線程的建立和銷燬都是須要耗費資源的,設計Executor框架的目的就是爲了在上層可以對這些異步任務進行有效地管理和調度。小程序

1.2 調度模型

咱們能夠把Executor框架想象成一個公司,開發者所須要完成的任務則是一個訂單,那麼任務的執行能夠分解爲下面這個過程:bash

  • 開發者將訂單提交給公司
  • 公司把訂單指派給對應的員工
  • 公司員工將訂單交給工廠
  • 工廠員工執行訂單

訂單、公司、公司員工、工廠和工廠員工這幾個概念的映射以下圖所示: 服務器

Executor框架對於內部線程的調度過程,就能夠理解爲公司對於員工的管理機制,而這一過程對於開發者是不可見的。框架

2、Executor 框架

整個Executor的框架主要由三個部分組成:異步

  • FutureTask:任務
  • ThreadPoolExecutor:常規任務管理者
  • ScheduledThreadPoolExecutor:週期任務管理者

下面,咱們就分這三個部分來簡要介紹一下涉及到的相關類。ui

2.1 任務

與任務相關的類的繼承關係以下圖所示: spa

當咱們向ThreadPoolExecutor或者ScheduledThreadPoolExecutor提交任務時,有如下四種方式:線程

public void execute(Runnable command)

public Future<?> submit(Runnable task)
public <T> Future<T> submit(Runnable task, T result)
public <T> Future<T> submit(Callable<T> task)
複製代碼
  • 當經過execute方法提交一個Runnable的實現類時,不會獲得返回的結果
  • 當經過submit方法提交一個Runnable或者Callable的實現類時,會返回一個Future的實現類,在目前JDK的實現當中:
  • 提交到ThreadPoolExecutor,返回FutureTask
  • 提交到ScheduledThreadPoolExecutor,返回ScheduledFutureTask

Future接口所提供的方法提供了下面幾個功能:設計

  • 經過isCancelled()isDone()方法來獲取任務當前的狀態
  • 經過cancel()來取消任務的執行
  • 經過get()方法來阻塞地獲取任務的執行結果

2.2 常規任務管理者

與常規任務執行者相關的類的繼承關係以下: 3d

ThreadPoolExecutor一般做爲常規任務的管理者,根據線程池的大小、工做隊列的區別,能夠實現不一樣的任務管理策略。

通常狀況下,一般使用工廠類Executors來建立不一樣類型ThreadPoolExecutor

  • FixedThreadPool:爲了知足限制當前線程數量的場景,適用於負載比較重的服務器。
  • SingleThreadPoolExecutor:適用於須要保證順序地執行各個任務,在任意時間點,不會有多個活動的應用場景。
  • CacheThreadPool:大小無界的線程池,適用於執行不少的短時間異步任務的小程序或者是負載較輕的服務器。

2.3 週期任務管理者

與週期任務有關的類的繼承關係以下:

ScheduledThreadPoolExecutor相比於ThreadPoolExecutor,它主要用來在給定的延遲以後運行任務,或者按期執行任務。和ThreadPoolExecutor相似,咱們也能夠經過Executors類來得到它不一樣的實現:

  • ScheduledThreadPoolExecutor:適用於須要多個後臺線程執行週期任務,同時爲了知足資源管理的需求而須要限制後臺線程的數量的應用場景。
  • SingleThreadScheduledExecutor:適用於須要單個後臺線程執行週期任務,同時須要保證順序地執行各個任務的應用場景。

3、小結

經過Executor框架,就能夠把工做單元與執行機制進行分離,開發者只須要把須要執行的任務經過Runnable或者Callable封裝成爲執行單元,具體的執行機制則由Executor的實現類去處理,免去了開發者對於任務的管理成本。

這篇文章,主要是對Executor框架進行了一個簡要的介紹,以後咱們會深刻到第二節討論的三個部分當中,分析Executor內部對於線程管理的實現機制。

相關文章
相關標籤/搜索