最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java線程池ThreadPoolExecutor實(shí)現(xiàn)原理詳解

 更新時(shí)間:2023年12月16日 10:57:29   作者:那個(gè)天真的人  
這篇文章主要介紹了java線程池ThreadPoolExecutor實(shí)現(xiàn)原理詳解,ThreadPoolExecutor是線程池實(shí)現(xiàn)類,會(huì)動(dòng)態(tài)創(chuàng)建多個(gè)線程,并發(fā)執(zhí)行提交的多個(gè)任務(wù),需要的朋友可以參考下

前言

做java開發(fā)的,一般都避免不了要面對(duì)java線程池技術(shù),像tomcat之類的容器天然就支持多線程。

即使是做偏后端技術(shù),如處理一些消息,執(zhí)行一些計(jì)算任務(wù),也經(jīng)常需要用到線程池技術(shù)。

鑒于線程池技術(shù)的重要性,接下來(lái)會(huì)分多篇介紹java中提供的ThreadPoolExecutor線程池實(shí)現(xiàn)的底層機(jī)制。

只有對(duì)機(jī)制了然于胸,才能更好駕馭這把利器。

線程池技術(shù)演示流程

  • 關(guān)鍵概念: 如果說(shuō)怎么最容易了解線程池的實(shí)現(xiàn)原理,那就是一步一步動(dòng)態(tài)的演示。為了便于理解,這里先介紹幾個(gè)線程池用到的概念。
  • ThreadPoolExecutor: 這是線程池實(shí)現(xiàn)類,會(huì)動(dòng)態(tài)創(chuàng)建多個(gè)線程,并發(fā)執(zhí)行提交的多個(gè)任務(wù);
  • Worker: 是個(gè)Runnable實(shí)現(xiàn)類來(lái)的,內(nèi)部會(huì)創(chuàng)建一個(gè)線程,一直循環(huán)不斷執(zhí)行任務(wù),所以可以認(rèn)為一個(gè)Worker就是一個(gè)工作線程;
  • corePoolSize: 當(dāng)池中總線程數(shù)<corePoolSize時(shí),提交一個(gè)任務(wù)創(chuàng)建一個(gè)新線程,而不管已經(jīng)存在的線程是不是閑著,通常情況下,一旦線程數(shù)達(dá) 到了corePoolSize,那么池中總線程數(shù)是不會(huì)跌破到corePoolSize以下的。(除非 allowCoreThreadTimeOut=true并且keepAliveTime>0);
  • maximumPoolSize: 當(dāng)池中線程數(shù)達(dá)到了corePoolSize,這時(shí)候新提交的任務(wù)就會(huì)放入等待隊(duì)列中,一般情況下,這些任務(wù)會(huì)被前面創(chuàng)建的 corePoolSize個(gè)線程執(zhí)行。當(dāng)任務(wù)提交速度過(guò)快,隊(duì)列滿了,這時(shí)候,如果當(dāng)前總線程數(shù)<maximumPoolSize,那么線程池會(huì)創(chuàng)建一個(gè)新的線程來(lái)執(zhí)行新提交的任務(wù),否則根據(jù)策略放棄任務(wù);
  • keepAliveTime:存活時(shí)間,分兩種情況: (1)allowCoreThreadTimeOut=true,所有線程,一旦創(chuàng)建后,在keepAliveTime時(shí)間內(nèi),如果沒(méi)有任務(wù)可以執(zhí)行,則該線程會(huì)退出并銷毀,這樣的好處是系統(tǒng)不忙時(shí)可以回收線程資源;(2)allowCoreThreadTimeOut=false,如果總線程數(shù)<=corePoolSize,那么這些線程是不會(huì)退出的,他們會(huì)一直不斷的等待任務(wù)并執(zhí)行,哪怕當(dāng)前沒(méi)有任務(wù),但如果線程數(shù)>corePoolSize,而且一旦一個(gè)線程閑的時(shí)間超過(guò) keepAliveTime則會(huì)退出,但一旦降低到corePoolSize,則不會(huì)再退出了。
  • allowCoreThreadTimeOut: 用于決定是否在系統(tǒng)閑時(shí)可以逐步回收所有的線程,如果為allowCoreThreadTimeOut=true,必須結(jié)合keepAliveTime一起使用,用于決定當(dāng)線程數(shù)<corePoolSize時(shí),是否要回收這些線程。
  • workQueue:這是一個(gè)阻塞隊(duì)列,當(dāng)線程數(shù)>=corePoolSize,這時(shí)候提交的任務(wù)將會(huì)放入阻塞隊(duì)列中,如果阻塞隊(duì)列是無(wú)界的,那么總的線程數(shù)是不可能>corePoolSize的,即maximumPoolSize屬性就是無(wú)用的;如果阻塞隊(duì)列是有界的,而且未滿,則任務(wù)入隊(duì),否則根據(jù)maximumPoolSize的值判斷是要新建線程執(zhí)行新任務(wù)或者是根據(jù)策略丟棄任務(wù)。

有了以上的概念,接下來(lái)將根據(jù) allowCoreThreadTimeOut的值分兩種場(chǎng)景進(jìn)行演示說(shuō)明。

演示一: allowCoreThreadTimeOut=true

1、 初值設(shè)定: corePoolSize=2; maximumPoolSize=3;keepAliveTime=10s; workQueue容量為2; 初始狀態(tài)圖如下所示:

這里寫圖片描述

2、submit一個(gè)任務(wù)A,由于總線程數(shù)0<corePoolSize; 此時(shí)會(huì)創(chuàng)建一個(gè)線程執(zhí)行任務(wù)A,狀態(tài)圖如下:

這里寫圖片描述

3、submit一個(gè)任務(wù)B,由于總線程數(shù)1<corePoolSize,此時(shí)會(huì)創(chuàng)建一個(gè)線程執(zhí)行任務(wù)B,狀態(tài)圖如下:

這里寫圖片描述

4、submit一個(gè)任務(wù)C,由于總線程數(shù) 2=corePoolSize,workQueue不滿,這時(shí)候任務(wù)C入隊(duì)列,狀態(tài)圖如下:

這里寫圖片描述

5、submit一個(gè)任務(wù)D,很明顯,任務(wù)D入隊(duì)列,狀態(tài)圖如下:

這里寫圖片描述

6、submit一個(gè)任務(wù)E,這時(shí)候,線程數(shù)2=corePoolSize,workQueue也已經(jīng)滿了,判斷發(fā)現(xiàn)線程數(shù)2<maximumPoolSize,所以繼續(xù)創(chuàng)建線程執(zhí)行任務(wù)E,狀態(tài)圖如下:

這里寫圖片描述

7、submit一個(gè)任務(wù)F,這時(shí)候,2=corePoolSize,workQueue已滿,判斷發(fā)現(xiàn)線程數(shù)3=maximumPoolSize,這種情況下,線程池會(huì)根據(jù)策略來(lái)決定是否要放棄當(dāng)前任務(wù),或者是把workQueue中一個(gè)任務(wù)刪除,然后入隊(duì)新的任務(wù),也可以自定義策略,比如,持久化到DB之類的,或者是發(fā)出警報(bào)。我們假設(shè)是直接丟棄策略,這時(shí)候狀態(tài)圖不變。

8、這會(huì)沒(méi)有新任務(wù)到來(lái)了,各個(gè)任務(wù)陸續(xù)執(zhí)行完了,包括隊(duì)列中的C和D也執(zhí)行完了,這時(shí)候,由于當(dāng)前場(chǎng)景為allowCoreThreadTimeOut=true,如果在等待keepAliveTime時(shí)間后線程仍舊無(wú)法獲取新的任務(wù),線程將會(huì)自行退出,這將導(dǎo)致最終所有線程都退出了,也就是又再次回到了原始狀態(tài),如下圖所示:

這里寫圖片描述

說(shuō)得更簡(jiǎn)單一些就是:在 allowCoreThreadTimeOut=true時(shí),如果一個(gè)線程等了keepAliveTime還無(wú)法獲取新任務(wù),則退出。

演示二:allowCoreThreadTimeOut=false

1~7 的步驟與狀態(tài)跟“演示一”是一樣的,所以這里不再贅述,這時(shí)候狀態(tài)圖如下:

這里寫圖片描述

8、這會(huì)沒(méi)有新任務(wù)到來(lái)了,各個(gè)任務(wù)陸續(xù)執(zhí)行完了,包括隊(duì)列中的C和D也執(zhí)行完了,這時(shí)候,由于當(dāng)前場(chǎng)景為allowCoreThreadTimeOut=false,并且線程數(shù)3>corePoolSize,這時(shí)候每個(gè)線程都感知到線程數(shù)過(guò)多,所以它們都會(huì)嘗試把自己停止掉,實(shí)現(xiàn)中最終只會(huì)停止一個(gè)線程,剩余線程數(shù)2=corePoolSize,接下來(lái),哪怕一直沒(méi)有新任務(wù)來(lái),這corePoolSize個(gè)線程也不會(huì)退出,一直存活著等待接收任務(wù)。這時(shí)候,狀態(tài)圖如下:

這里寫圖片描述

線程池的狀態(tài)

前一部分演示了線程池的基本實(shí)現(xiàn)原理,這一小節(jié)介紹一下線程池的狀態(tài),線程池概括上講有5種狀態(tài),如下圖所示:

這里寫圖片描述

  • RUNNING狀態(tài): 創(chuàng)建線程池的時(shí)候,線程池的初始狀態(tài)為 RUNNING,接著就可以提交任務(wù)執(zhí)行了。
  • SHUTDOWN狀態(tài): 當(dāng)在RUNNING狀態(tài)調(diào)用shutdown()時(shí),線程池狀態(tài)會(huì)被改為SHUTDOWN,這時(shí)候,submit任務(wù)的時(shí)候,會(huì)被拒絕,可以使用多種拒絕策略, 比如最簡(jiǎn)單就是直接丟棄任務(wù)。至于正在執(zhí)行中的線程,會(huì)繼續(xù)執(zhí)行,同時(shí)會(huì)把阻塞隊(duì)列中的任務(wù)也一并執(zhí)行完畢,等到全部任務(wù)執(zhí)行完畢,線程池會(huì)進(jìn)入 TIDYING狀態(tài),等執(zhí)行鉤子方法terminated()之后,就會(huì)進(jìn)入最終狀態(tài)TERMINATED,這時(shí)候,整個(gè)線程池完全終止。
  • STOP狀態(tài): 當(dāng)在RUNNING狀態(tài)調(diào)用shutdownNow()時(shí),線程池狀態(tài)會(huì)被改為STOP,這時(shí)候,submit任務(wù)會(huì)被拒絕,那么如果有任務(wù)執(zhí)行到一半,該怎么處理?其實(shí),執(zhí)行shutdownNow()時(shí),會(huì)中斷各個(gè)工作線程,所以任務(wù)會(huì)如何執(zhí)行要看任務(wù)做的是什么事情,有沒(méi)有處理中斷異常。而阻塞隊(duì)列如何有任務(wù),這些任務(wù)將不會(huì)再執(zhí)行,shutdownNow()執(zhí)行后,將會(huì)返回阻塞隊(duì)列中的未執(zhí)行的任務(wù)列表。
  • TIDYING狀態(tài): TIDYING只是一個(gè)過(guò)渡狀態(tài),當(dāng)所有工作線程都停止后,線程池的狀態(tài)會(huì)進(jìn)入TIDYING,然后執(zhí)行一個(gè)鉤子方法terminated(),最后線程池會(huì)進(jìn)入TERMINATED狀態(tài)。
  • TERMINATED狀態(tài): 線程池終止?fàn)顟B(tài),這個(gè)沒(méi)什么可說(shuō)的了,大家都明白。

總結(jié)

理解線程池最主要是要理解線程池幾個(gè)主要的配置參數(shù),如果不看實(shí)現(xiàn)細(xì)節(jié),原理還是比較簡(jiǎn)單的。在了解原理的基礎(chǔ)上再去看代碼,就會(huì)事半功倍。

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

相關(guān)文章

  • SpringBoot利用validation實(shí)現(xiàn)優(yōu)雅的校驗(yàn)參數(shù)

    SpringBoot利用validation實(shí)現(xiàn)優(yōu)雅的校驗(yàn)參數(shù)

    數(shù)據(jù)的校驗(yàn)是交互式網(wǎng)站一個(gè)不可或缺的功能,如果數(shù)據(jù)庫(kù)中出現(xiàn)一個(gè)非法的郵箱格式,會(huì)讓運(yùn)維人員頭疼不已。本文將介紹如何利用validation來(lái)對(duì)數(shù)據(jù)進(jìn)行校驗(yàn),感興趣的可以跟隨小編一起學(xué)習(xí)一下
    2022-06-06
  • Java基于Socket實(shí)現(xiàn)HTTP下載客戶端

    Java基于Socket實(shí)現(xiàn)HTTP下載客戶端

    這篇文章主要介紹了Java基于Socket實(shí)現(xiàn)HTTP下載客戶端的相關(guān)資料,感興趣的小伙伴們可以參考一下
    2016-01-01
  • Netty中序列化的作用及自定義協(xié)議詳解

    Netty中序列化的作用及自定義協(xié)議詳解

    這篇文章主要介紹了Netty中序列化的作用及自定義協(xié)議詳解,Netty自身就支持很多種協(xié)議比如Http、Websocket等等,但如果用來(lái)作為自己的RPC框架通常會(huì)自定義協(xié)議,所以這也是本文的重點(diǎn),需要的朋友可以參考下
    2023-12-12
  • Java編程實(shí)現(xiàn)中英混合字符串?dāng)?shù)組按首字母排序的方法

    Java編程實(shí)現(xiàn)中英混合字符串?dāng)?shù)組按首字母排序的方法

    這篇文章主要介紹了Java編程實(shí)現(xiàn)中英混合字符串?dāng)?shù)組按首字母排序的方法,涉及Java字符串操作及拼音轉(zhuǎn)換的相關(guān)使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • Java事件處理步驟講解

    Java事件處理步驟講解

    今天小編就為大家分享一篇關(guān)于Java事件處理步驟講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • 前后端分離跨域springBoot跨域有效解決問(wèn)題

    前后端分離跨域springBoot跨域有效解決問(wèn)題

    這篇文章主要介紹了前后端分離跨域springBoot跨域有效解決問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Dwr3.0純注解(純Java Code配置)配置與應(yīng)用淺析二之前端調(diào)用后端

    Dwr3.0純注解(純Java Code配置)配置與應(yīng)用淺析二之前端調(diào)用后端

    我們講到了后端純Java Code的Dwr3配置,完全去掉了dwr.xml配置文件,但是對(duì)于使用注解的類卻沒(méi)有使用包掃描,而是在Servlet初始化參數(shù)的classes里面加入了我們的Service組件的聲明暴露,對(duì)于這個(gè)問(wèn)題需要后面我們?cè)偌?xì)細(xì)研究下這篇文章,主要分析介紹前端怎么直接調(diào)用后端
    2016-04-04
  • Java中String的JdbcTemplate連接SQLServer數(shù)據(jù)庫(kù)的方法

    Java中String的JdbcTemplate連接SQLServer數(shù)據(jù)庫(kù)的方法

    這篇文章主要介紹了Java中String的JdbcTemplate連接SQLServer數(shù)據(jù)庫(kù)的方法,在研發(fā)過(guò)程中我們需要與其他系統(tǒng)對(duì)接的場(chǎng)景,連接SQLServer拉取數(shù)據(jù),所以就用jdbc連接數(shù)據(jù)庫(kù)的方式連接外部數(shù)據(jù)源,需要的朋友可以參考下
    2021-10-10
  • Java中HttpServletResponse響應(yīng)中文出現(xiàn)亂碼問(wèn)題

    Java中HttpServletResponse響應(yīng)中文出現(xiàn)亂碼問(wèn)題

    這篇文章主要介紹了Java中HttpServletResponse響應(yīng)中文出現(xiàn)亂碼問(wèn)題的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-06-06
  • Spring spel表達(dá)式使用方法示例

    Spring spel表達(dá)式使用方法示例

    這篇文章主要介紹了Spring spel表達(dá)式使用方法示例,通過(guò)一些實(shí)例向大家展示了spel表達(dá)式的用法,需要的朋友可以了解下。
    2017-09-09

最新評(píng)論

日喀则市| 五常市| 山阴县| 盐亭县| 额尔古纳市| 南昌市| 南和县| 哈密市| 长沙市| 昂仁县| 夏津县| 公主岭市| 哈尔滨市| 鹤庆县| 宜兰市| 峡江县| 乐陵市| 美姑县| 崇州市| 本溪市| 乌审旗| 屯留县| 余姚市| 龙南县| 酉阳| 合肥市| 阿勒泰市| 航空| 巫山县| 丰城市| 栾城县| 安泽县| 福安市| 大冶市| 会宁县| 土默特右旗| 鄂州市| 民丰县| 梅河口市| 长顺县| 深泽县|