欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中的ThreadPoolExecutor線程池詳解

 更新時(shí)間:2023年12月28日 08:47:09   作者:Java都不學(xué)  
這篇文章主要介紹了Java中的ThreadPoolExecutor線程池詳解,當(dāng)線程池中的線程數(shù)大于 corePoolSize 時(shí),keepAliveTime 為多余的空閑線程等待新任務(wù)的最長(zhǎng)時(shí)間,超過(guò)這個(gè)時(shí)間后多余的線程將被終止,需要的朋友可以參考下

概述

Executor 框架最核心的類是 ThreadPoolExecutor,它是線程池的實(shí)現(xiàn)類,主要由下列 4 個(gè)組件構(gòu)成。

  • corePool:核心線程池的大小。
  • maximumPool:最大線程池的大小。
  • BlockingQueue:用來(lái)暫時(shí)保存任務(wù)的工作隊(duì)列。
  • RejectedExecutionHandler:當(dāng) ThreadPoolExecutor 已經(jīng)關(guān)閉或 ThreadPoolExecutor 已經(jīng)飽和時(shí)(達(dá)到了最大線程池大小且工作隊(duì)列已滿),execute()方法將要調(diào)用的 Handler。

通過(guò) Executor 框架的工具類 Executors,可以創(chuàng)建 3 種類型的 ThreadPoolExecutor。

  • FixedThreadPool
  • SingleThreadExecutor
  • CachedThreadPool

FixedThreadPool 詳解

FixedThreadPool 被稱為可重用固定線程數(shù)的線程池。

public static ExecutorService newFixedThreadPool(int nThreads) {
     return new ThreadPoolExecutor(nThreads, nThreads,
                 0L, TimeUnit.MILLISECONDS,
                 new LinkedBlockingQueue<Runnable>());
}

FixedThreadPool 的 corePoolSize 和 maximumPoolSize 都被設(shè)置為創(chuàng)建 FixedThreadPool 時(shí)指定的參數(shù) nThreads。

當(dāng)線程池中的線程數(shù)大于 corePoolSize 時(shí),keepAliveTime 為多余的空閑線程等待新任務(wù)的最長(zhǎng)時(shí)間,超過(guò)這個(gè)時(shí)間后多余的線程將被終止。

這里把 keepAliveTime 設(shè)置為 0L,意味著多余的空閑線程會(huì)被立即終止。

1) 如果當(dāng)前運(yùn)行的線程數(shù)少于 corePoolSize,則創(chuàng)建新線程來(lái)執(zhí)行任務(wù)。

2) 在線程池完成預(yù)熱之后(當(dāng)前運(yùn)行的線程數(shù)等于 corePoolSize),將任務(wù)加入 LinkedBlockingQueue。

3) 線程執(zhí)行完 1 中的任務(wù)后,會(huì)在循環(huán)中反復(fù)從 LinkedBlockingQueue 獲取任務(wù)來(lái) 執(zhí)行。

4) FixedThreadPool 使用無(wú)界隊(duì)列 LinkedBlockingQueue 作為線程池的工作隊(duì)列(隊(duì)列的容量為 Integer.MAX_VALUE)。

使用無(wú)界隊(duì)列作為工作隊(duì)列會(huì)對(duì)線程池帶來(lái)如下影響。

  • 當(dāng)線程池中的線程數(shù)達(dá)到 corePoolSize 后,新任務(wù)將在無(wú)界隊(duì)列 中等待,因此線程池中的線程數(shù)不會(huì)超過(guò) corePoolSize。
  • 由于 1,使用無(wú)界隊(duì)列時(shí) maximumPoolSize 將是一個(gè)無(wú)效參數(shù)。
  • 由于 1 和 2,使用無(wú)界隊(duì)列時(shí) keepAliveTime 將是一個(gè)無(wú)效參數(shù)。
  • 由于使用無(wú)界隊(duì)列,運(yùn)行中的 FixedThreadPool(未執(zhí)行方法 shutdown()或 shutdownNow())不會(huì)拒絕任務(wù)(不會(huì)調(diào)用 RejectedExecutionHandler.rejectedExecution 方法)。

SingleThreadExecutor 詳解

SingleThreadExecutor 是使用單個(gè) worker 線程的 Executor。

public static ExecutorService newSingleThreadExecutor() {
     return new FinalizableDelegatedExecutorService(
             new ThreadPoolExecutor(
                    1, 
                    1, 
                    0L, 
                    TimeUnit.MILLISECONDS, 
                    new LinkedBlockingQueue<Runnable>()
             )
         );
}

SingleThreadExecutor 的 corePoolSize 和 maximumPoolSize 被設(shè)置為1。

其他參數(shù)與 FixedThreadPool 相同。

SingleThreadExecutor 使用無(wú)界隊(duì)列 LinkedBlockingQueue 作為線程池的工作隊(duì)列(隊(duì)列的容量為 Integer.MAX_VALUE)。

SingleThreadExecutor 使用無(wú)界隊(duì)列作為工作隊(duì)列對(duì)線程池帶來(lái)的影響與 FixedThreadPool 相同。

1) 如果當(dāng)前運(yùn)行的線程數(shù)少于 corePoolSize(即線程池中無(wú)運(yùn)行的線程),則創(chuàng)建一個(gè)新線程來(lái)執(zhí)行任務(wù)。

2) 在線程池完成預(yù)熱之后(當(dāng)前線程池中有一個(gè)運(yùn)行的線程),將任務(wù)加入 LinkedBlockingQueue。

3) 線程執(zhí)行完 1 中的任務(wù)后,會(huì)在一個(gè)無(wú)限循環(huán)中反復(fù)從 LinkedBlockingQueue 獲取任務(wù)來(lái)執(zhí)行。

CachedThreadPool 詳解

CachedThreadPool 是一個(gè)會(huì)根據(jù)需要?jiǎng)?chuàng)建新線程的線程池。

public static ExecutorService newCachedThreadPool() {
     return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
             new SynchronousQueue<Runnable>());
}

CachedThreadPool 的 corePoolSize 被設(shè)置為 0,即 corePool 為空;maximumPoolSize 被設(shè)置為 Integer.MAX_VALUE,即 maximumPool 是無(wú)界的。這里把 keepAliveTime 設(shè)置為 60L,意味著 CachedThreadPool 中的空閑線程等待新任務(wù)的最長(zhǎng)時(shí)間為 60 秒,空閑線程超過(guò) 60 秒后將會(huì)被終止。

FixedThreadPool 和 SingleThreadExecutor 使用無(wú)界隊(duì)列 LinkedBlockingQueue 作為線程池的工作隊(duì)列。

CachedThreadPool 使用沒(méi)有容量的 SynchronousQueue 作為線程池的工作隊(duì)列,但 CachedThreadPool 的 maximumPool 是無(wú)界的。

這意味著,如果主線程提交任務(wù)的速度高于 maximumPool 中線程處理任務(wù)的速度時(shí),CachedThreadPool 會(huì)不斷創(chuàng)建新線程。極端情況下, CachedThreadPool 會(huì)因?yàn)閯?chuàng)建過(guò)多線程而耗盡 CPU 和內(nèi)存資源。

1) 首先執(zhí)行 SynchronousQueue.offer(Runnable task)。如果當(dāng)前 maximumPool 中有空閑線程正在執(zhí)行 SynchronousQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS),那么主線程執(zhí)行 offer 操作與空閑線程執(zhí)行的 poll 操作配對(duì)成功,主線程把任務(wù)交給空閑線程執(zhí)行,execute()方法執(zhí)行完成;否則執(zhí)行下面的步驟 2)。

2) 當(dāng)初始 maximumPool 為空,或者 maximumPool 中當(dāng)前沒(méi)有空閑線程時(shí),將沒(méi)有線程執(zhí)行 SynchronousQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS)。這種情況下,步驟 1)將失敗。此時(shí) CachedThreadPool 會(huì)創(chuàng)建一個(gè)新線程執(zhí)行任務(wù),execute()方法執(zhí)行完成。

3) 在步驟 2)中新創(chuàng)建的線程將任務(wù)執(zhí)行完后,會(huì)執(zhí)行 SynchronousQueue.poll (keepAliveTime,TimeUnit.NANOSECONDS)。這個(gè) poll 操作會(huì)讓空閑線程最多在 SynchronousQueue 中等待 60 秒鐘。如果 60 秒鐘內(nèi)主線程提交了一個(gè)新任務(wù)(主線程執(zhí)行步驟 1)),那么這個(gè)空閑線程將執(zhí)行主線程提交的新任務(wù);否則,這個(gè)空閑線程將終止。由于空閑 60 秒的空閑線程會(huì)被終止,因此長(zhǎng)時(shí)間保持空閑的 CachedThreadPool 不會(huì)使用任何資源。

SynchronousQueue 是一個(gè)沒(méi)有容量的阻塞隊(duì)列。每個(gè)插入操作必須等 待另一個(gè)線程的對(duì)應(yīng)移除操作,反之亦然。CachedThreadPool 使用 SynchronousQueue, 把主線程提交的任務(wù)傳遞給空閑線程執(zhí)行。

CachedThreadPool 的任務(wù)傳遞示意圖

到此這篇關(guān)于Java中的ThreadPoolExecutor線程池詳解的文章就介紹到這了,更多相關(guān)ThreadPoolExecutor線程池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot開(kāi)發(fā)中的組件和容器詳解

    SpringBoot開(kāi)發(fā)中的組件和容器詳解

    這篇文章主要介紹了SpringBoot開(kāi)發(fā)中的組件和容器詳解,SpringBoot 提供了一個(gè)內(nèi)嵌的 Tomcat 容器作為默認(rèn)的 Web 容器,同時(shí)還支持其他 Web 容器和應(yīng)用服務(wù)器,需要的朋友可以參考下
    2023-09-09
  • 關(guān)于Java中HashCode方法的深入理解

    關(guān)于Java中HashCode方法的深入理解

    這篇文章主要給大家介紹了關(guān)于Java中HashCode方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • 解決Springboot整合shiro時(shí)靜態(tài)資源被攔截的問(wèn)題

    解決Springboot整合shiro時(shí)靜態(tài)資源被攔截的問(wèn)題

    這篇文章主要介紹了解決Springboot整合shiro時(shí)靜態(tài)資源被攔截的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • js實(shí)現(xiàn)拖拽拼圖游戲

    js實(shí)現(xiàn)拖拽拼圖游戲

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)拖拽拼圖游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • java拷貝指定目錄下所有內(nèi)容到minIO代碼實(shí)例

    java拷貝指定目錄下所有內(nèi)容到minIO代碼實(shí)例

    這篇文章主要介紹了java拷貝指定目錄下所有內(nèi)容到minIO代碼實(shí)例,創(chuàng)建桶 直接使用工具類先判斷,再創(chuàng)建即可,創(chuàng)建文件夾,需要注意以"/"結(jié)尾,實(shí)際也是在minIO上創(chuàng)建文件,只是作為目錄的表現(xiàn)形式展示,需要的朋友可以參考下
    2024-01-01
  • JAVA 中Spring的@Async用法總結(jié)

    JAVA 中Spring的@Async用法總結(jié)

    這篇文章主要介紹了JAVA 中Spring的@Async用法總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Java數(shù)組的去重

    Java數(shù)組的去重

    這篇文章主要介紹了Java數(shù)組去重,結(jié)合實(shí)例形式分析了Java針對(duì)數(shù)組的去重,需要的朋友可以參考下,希望能夠給你帶來(lái)幫助
    2021-10-10
  • Java中Date時(shí)區(qū)的轉(zhuǎn)換代碼示例

    Java中Date時(shí)區(qū)的轉(zhuǎn)換代碼示例

    這篇文章主要給大家介紹了關(guān)于Java中Date時(shí)區(qū)轉(zhuǎn)換的相關(guān)資料,當(dāng)在不同的時(shí)區(qū)使用相同程序,時(shí)間的值只會(huì)為當(dāng)?shù)貢r(shí)間,這樣就會(huì)造成時(shí)間混亂,需要的朋友可以參考下
    2023-07-07
  • IntelliJ IDEA下SpringBoot如何指定某一個(gè)配置文件啟動(dòng)項(xiàng)目

    IntelliJ IDEA下SpringBoot如何指定某一個(gè)配置文件啟動(dòng)項(xiàng)目

    這篇文章主要介紹了IntelliJ IDEA下SpringBoot如何指定某一個(gè)配置文件啟動(dòng)項(xiàng)目問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的線程池代碼示例

    Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的線程池代碼示例

    線程池是管理線程的一個(gè)池子,通過(guò)阻塞隊(duì)列管理任務(wù),主要參數(shù)包括corePoolSize、maximumPoolSize、keepAliveTime等,這篇文章主要介紹了Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的線程池的相關(guān)資料,需要的朋友可以參考下
    2024-09-09

最新評(píng)論