日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Executor框架、ThreadPoolExecutor、3种常见的线程池

發(fā)布時間:2024/10/14 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Executor框架、ThreadPoolExecutor、3种常见的线程池 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

參考:https://blog.csdn.net/javazejian/article/details/50890554

1. Executor框架

為什么需要線程池?

在java中,使用線程來執(zhí)行異步任務(wù)時,線程的創(chuàng)建和銷毀需要一定的開銷,如果我們?yōu)槊恳粋€任務(wù)創(chuàng)建一個新的線程來執(zhí)行的話,那么這些線程的創(chuàng)建與銷毀將消耗大量的計算資源。

同時為每一個任務(wù)創(chuàng)建一個新線程來執(zhí)行,這樣的方式可能會使處于高負荷狀態(tài)的應(yīng)用最終崩潰。

所以線程池的出現(xiàn)為解決這個問題帶來曙光。

我們將在線程池中創(chuàng)建若干條線程,當(dāng)有任務(wù)需要執(zhí)行時就從該線程池中獲取一條線程來執(zhí)行任務(wù),如果一時間任務(wù)過多,超出線程池的線程數(shù)量,那么后面的線程任務(wù)就進入一個等待隊列進行等待,直到線程池有線程處于空閑時才從等待隊列獲取要執(zhí)行的任務(wù)進行處理,以此循環(huán).....這樣就大大減少了線程創(chuàng)建和銷毀的開銷,也會緩解我們的應(yīng)用處于超負荷時的情況。

1.1 Executor框架的兩級調(diào)度模型

在java線程啟動時會創(chuàng)建一個本地操作系統(tǒng)線程,當(dāng)該java線程終止時,這個操作系統(tǒng)線程也會被回收。

而每一個java線程都會被一對一映射為本地操作系統(tǒng)的線程,操作系統(tǒng)會調(diào)度所有的線程并將它們分別給可用的CPU。

而所謂的映射方式是這樣實現(xiàn)的:

  • 在上層,java多線程程序通過把應(yīng)用分為若干個任務(wù),然后使用用戶級的調(diào)度器(Executor框架)將這些任務(wù)映射為固定數(shù)量的線程;
  • 在底層,操作系統(tǒng)內(nèi)核將這些線程映射到硬件處理器上。這樣種兩級調(diào)度模型如下圖所示:

從圖中我們可以看出,應(yīng)用程序通過Executor框架控制上層的調(diào)度,而下層的調(diào)度由操作系統(tǒng)內(nèi)核控制,下層的調(diào)度不受應(yīng)用程序的控制。

1.2 Executor框架的結(jié)構(gòu)

Executor框架的結(jié)構(gòu)主要包括3個部分

  • 任務(wù):包括被執(zhí)行任務(wù)需要實現(xiàn)的接口:Runnable接口或Callable接口
  • 任務(wù)的執(zhí)行:包括任務(wù)執(zhí)行機制的核心接口Executor,以及繼承自Executor的EexcutorService接口。Exrcutor有兩個關(guān)鍵類實現(xiàn)了ExecutorService接口(ThreadPoolExecutor和ScheduledThreadPoolExecutor)
  • 異步計算的結(jié)果:包括接口Future和實現(xiàn)Future接口的FutureTask類
  • 這些類間的關(guān)系的UML圖:

    • Extecutor是一個接口,它是Executor框架的基礎(chǔ),它將任務(wù)的提交與任務(wù)的執(zhí)行分離開來。
    • ThreadPoolExecutor是線程池的核心實現(xiàn)類,用來執(zhí)行被提交的任務(wù)。
    • ScheduledThreadPoolExecutor是一個實現(xiàn)類,可以在給定的延遲后運行命令,或者定期執(zhí)行命令。
    • ScheduledThreadPoolExecutor比Timer更靈活,功能更強大。
    • Future接口和實現(xiàn)Future接口的FutureTask類,代表異步計算的結(jié)果。
    • Runnable接口和Callable接口的實現(xiàn)類,都可以被ThreadPoolExecutor或者ScheduledThreadPoolExecutor執(zhí)行。區(qū)別就是Runnable無法返回執(zhí)行結(jié)果,而Callable可以返回執(zhí)行結(jié)果。
    • Executor 和 ExectorService 這兩個接口的主要區(qū)別:
      • ExectorService 接口繼承了Executor 接口,是它的子接口;
      • Executor 接口定義了execute()方法用來接收一個Runnable接口的對象,而ExecutorService接口中的submit()方法可以接受Runnable和Callable接口的對象;
      • Executor 中的execute()方法不返回任何結(jié)果,ExecutorService的submit()方法可以通過一個Future對象返回運算結(jié)果;
      • ExecutorService允許客戶端提交一個任務(wù),并且還提供用來控制線程池的方法,比如:調(diào)用shutDown()方法終止線程池

    它們間的執(zhí)行關(guān)系:

    分析說明:

  • 主線程首先創(chuàng)建實現(xiàn)Runnable或Callable接口的任務(wù)對象;
  • 工具類Executors可以把一個Runnable對象封裝為一個Callable對象,使用如下兩種方式:
  • Executors.callable(Runnable task)
  • Executors.callable(Runnable task,Object resule)。
  • 然后可以把Runnable對象直接提交給ExecutorService執(zhí)行,方法為ExecutorService.execute(Runnable command);
  • 或者也可以把Runnable對象或者Callable對象提交給ExecutorService執(zhí)行,方法為ExecutorService.submit(Runnable task)或ExecutorService.submit(Callable<T> task)。
  • 這里需要注意的是如果執(zhí)行ExecutorService.submit(...),ExecutorService將返回一個實現(xiàn)Future接口的對象(其實就是FutureTask)。
  • 當(dāng)然由于FutureTask實現(xiàn)了Runnable接口,我們也可以直接創(chuàng)建FutureTask,然后提交給ExecutorService執(zhí)行。
  • 到此Executor框架的主要體系結(jié)構(gòu)我們都介紹完了,我們對此有了大概了解后,下面我們就重點聊聊兩個主要的線程池實現(xiàn)類。

    2.ThreadPoolExecutor

    3. 3種常見的線程池

    它們都直接或者間接地通過配置ThreadPoolExecutor來實現(xiàn)自己的功能特性,這個3種線程池分別是FixedThreadPool,CachedThreadPool,ScheduledThreadPool以及SingleThreadExecutor。

    ?

    總結(jié)

    以上是生活随笔為你收集整理的Executor框架、ThreadPoolExecutor、3种常见的线程池的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。