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

一、Executor 框架的調(diào)度模型

1.1 目的

在平時(shí)的開發(fā)中,我們經(jīng)常需要將一些耗時(shí)的任務(wù)放到異步線程當(dāng)中進(jìn)行處理,而線程的創(chuàng)建和銷毀都是需要耗費(fèi)資源的,設(shè)計(jì)Executor框架的目的就是為了在上層能夠?qū)@些異步任務(wù)進(jìn)行有效地管理和調(diào)度。

1.2 調(diào)度模型

我們可以把Executor框架想象成一個(gè)公司,開發(fā)者所需要完成的任務(wù)則是一個(gè)訂單,那么任務(wù)的執(zhí)行可以分解為下面這個(gè)過程:

  • 開發(fā)者將訂單提交給公司
  • 公司把訂單指派給對(duì)應(yīng)的員工
  • 公司員工將訂單交給工廠
  • 工廠員工執(zhí)行訂單

訂單、公司、公司員工、工廠和工廠員工這幾個(gè)概念的映射如下圖所示:


Executor框架對(duì)于內(nèi)部線程的調(diào)度過程,就可以理解為公司對(duì)于員工的管理機(jī)制,而這一過程對(duì)于開發(fā)者是不可見的。

二、Executor 框架

整個(gè)Executor的框架主要由三個(gè)部分組成:

  • FutureTask:任務(wù)
  • ThreadPoolExecutor:常規(guī)任務(wù)管理者
  • ScheduledThreadPoolExecutor:周期任務(wù)管理者

下面,我們就分這三個(gè)部分來(lái)簡(jiǎn)要介紹一下涉及到的相關(guān)類。

2.1 任務(wù)

與任務(wù)相關(guān)的類的繼承關(guān)系如下圖所示:


當(dāng)我們向ThreadPoolExecutor或者ScheduledThreadPoolExecutor提交任務(wù)時(shí),有以下四種方式:

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)
  • 當(dāng)通過execute方法提交一個(gè)Runnable的實(shí)現(xiàn)類時(shí),不會(huì)得到返回的結(jié)果
  • 當(dāng)通過submit方法提交一個(gè)Runnable或者Callable的實(shí)現(xiàn)類時(shí),會(huì)返回一個(gè)Future的實(shí)現(xiàn)類,在目前JDK的實(shí)現(xiàn)當(dāng)中:
  • 提交到ThreadPoolExecutor,返回FutureTask
  • 提交到ScheduledThreadPoolExecutor,返回ScheduledFutureTask

Future接口所提供的方法提供了下面幾個(gè)功能:

  • 通過isCancelled()isDone()方法來(lái)獲取任務(wù)當(dāng)前的狀態(tài)
  • 通過cancel()來(lái)取消任務(wù)的執(zhí)行
  • 通過get()方法來(lái)阻塞地獲取任務(wù)的執(zhí)行結(jié)果

2.2 常規(guī)任務(wù)管理者

與常規(guī)任務(wù)執(zhí)行者相關(guān)的類的繼承關(guān)系如下:


ThreadPoolExecutor通常作為常規(guī)任務(wù)的管理者,根據(jù)線程池的大小、工作隊(duì)列的區(qū)別,可以實(shí)現(xiàn)不同的任務(wù)管理策略。

一般情況下,通常使用工廠類Executors來(lái)創(chuàng)建不同類型ThreadPoolExecutor

  • FixedThreadPool:為了滿足限制當(dāng)前線程數(shù)量的場(chǎng)景,適用于負(fù)載比較重的服務(wù)器。
  • SingleThreadPoolExecutor:適用于需要保證順序地執(zhí)行各個(gè)任務(wù),在任意時(shí)間點(diǎn),不會(huì)有多個(gè)活動(dòng)的應(yīng)用場(chǎng)景。
  • CacheThreadPool:大小無(wú)界的線程池,適用于執(zhí)行很多的短期異步任務(wù)的小程序或者是負(fù)載較輕的服務(wù)器。

2.3 周期任務(wù)管理者

與周期任務(wù)有關(guān)的類的繼承關(guān)系如下:


ScheduledThreadPoolExecutor相比于ThreadPoolExecutor,它主要用來(lái)在給定的延遲之后運(yùn)行任務(wù),或者定期執(zhí)行任務(wù)。和ThreadPoolExecutor類似,我們也可以通過Executors類來(lái)獲得它不同的實(shí)現(xiàn):

  • ScheduledThreadPoolExecutor:適用于需要多個(gè)后臺(tái)線程執(zhí)行周期任務(wù),同時(shí)為了滿足資源管理的需求而需要限制后臺(tái)線程的數(shù)量的應(yīng)用場(chǎng)景。
  • SingleThreadScheduledExecutor:適用于需要單個(gè)后臺(tái)線程執(zhí)行周期任務(wù),同時(shí)需要保證順序地執(zhí)行各個(gè)任務(wù)的應(yīng)用場(chǎng)景。

三、小結(jié)

通過Executor框架,就可以把工作單元與執(zhí)行機(jī)制進(jìn)行分離,開發(fā)者只需要把需要執(zhí)行的任務(wù)通過Runnable或者Callable封裝成為執(zhí)行單元,具體的執(zhí)行機(jī)制則由Executor的實(shí)現(xiàn)類去處理,免去了開發(fā)者對(duì)于任務(wù)的管理成本。

這篇文章,主要是對(duì)Executor框架進(jìn)行了一個(gè)簡(jiǎn)要的介紹,之后我們會(huì)深入到第二節(jié)討論的三個(gè)部分當(dāng)中,分析Executor內(nèi)部對(duì)于線程管理的實(shí)現(xiàn)機(jī)制。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容