Java線程池實(shí)現(xiàn)原理總結(jié)
要理解實(shí)現(xiàn)原理,必須把線程池的幾個(gè)參數(shù)徹底搞懂,不要死記硬背
一、線程池參數(shù)
- 1、corePoolSize(必填):核心線程數(shù)。
- 2、maximumPoolSize(必填):最大線程數(shù)。
- 3、keepAliveTime(必填):線程空閑時(shí)長(zhǎng)。如果超過(guò)該時(shí)長(zhǎng),非核心線程就會(huì)被回收。
- 4、unit(必填):指定keepAliveTime的時(shí)間單位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。
- 5、workQueue(必填):任務(wù)隊(duì)列。通過(guò)線程池的execute()方法提交的Runnable對(duì)象將存儲(chǔ)在該隊(duì)列中。
- 6、threadFactory(可選):線程工廠。一般就用默認(rèn)的。
- 7、handler(可選):拒絕策略。當(dāng)線程數(shù)達(dá)到最大線程數(shù)時(shí)就要執(zhí)行飽和策略。
說(shuō)下核心線程數(shù)和最大線程數(shù)的區(qū)別
拒絕策略可選值:
1、AbortPolicy(默認(rèn)):放棄任務(wù)并拋出RejectedExecutionException異常。
2、CallerRunsPolicy:由調(diào)用線程處理該任務(wù)。
3、DiscardPolicy:放棄任務(wù),但是不拋出異常。可以配合這種模式進(jìn)行自定義的處理方式。
4、DiscardOldestPolicy:放棄隊(duì)列最早的未處理任務(wù),然后重新嘗試執(zhí)行任務(wù)。
二、線程池執(zhí)行流程
上個(gè)流程圖,先試著自己看下能不能看懂
簡(jiǎn)短的總結(jié)下線程池執(zhí)行流程:
- 1、一個(gè)任務(wù)提交到線程池后,如果當(dāng)前的線程數(shù)沒達(dá)到核心線程數(shù),則新建一個(gè)線程并且執(zhí)行新任務(wù),注意一點(diǎn),這個(gè)新任務(wù)執(zhí)行完后,該線程不會(huì)被銷毀;
- 2、如果達(dá)到了,則判斷任務(wù)隊(duì)列滿了沒,如果沒滿,則將任務(wù)放入任務(wù)隊(duì)列;
- 3、如果滿了,則判斷當(dāng)前線程數(shù)量是否達(dá)到最大線程數(shù),如果沒達(dá)到,則創(chuàng)建新線程來(lái)執(zhí)行任務(wù),注意,如果線程池中線程數(shù)量大于核心線程數(shù),每當(dāng)有線程超過(guò)了空閑時(shí)間,就會(huì)被銷毀,直到線程數(shù)量不大于核心線程數(shù);
- 4、如果達(dá)到了最大線程數(shù),并且任務(wù)隊(duì)列滿了,就會(huì)執(zhí)行飽和策略;
三、四種現(xiàn)成的線程池
不想自己new線程池的話,可以用現(xiàn)成的
1、定長(zhǎng)線程池(FixedThreadPool)
特點(diǎn):只有核心線程,線程數(shù)量固定,執(zhí)行完立即回收,任務(wù)隊(duì)列為鏈表結(jié)構(gòu)的有界隊(duì)列。
應(yīng)用場(chǎng)景:控制線程最大并發(fā)數(shù)
2、定時(shí)線程池(ScheduledThreadPool )
特點(diǎn):核心線程數(shù)量固定,非核心線程數(shù)量無(wú)限,執(zhí)行完閑置10ms后回收,任務(wù)隊(duì)列為延時(shí)阻塞隊(duì)列。
應(yīng)用場(chǎng)景:執(zhí)行定時(shí)或周期性的任務(wù)。
3、可緩存線程池(CachedThreadPool)
特點(diǎn):無(wú)核心線程,非核心線程數(shù)量無(wú)限,執(zhí)行完閑置60s后回收,任務(wù)隊(duì)列為不存儲(chǔ)元素的阻塞隊(duì)列。
應(yīng)用場(chǎng)景:執(zhí)行大量、耗時(shí)少的任務(wù)。
4、單線程化線程池(SingleThreadExecutor)
特點(diǎn):只有1個(gè)核心線程,無(wú)非核心線程,執(zhí)行完立即回收,任務(wù)隊(duì)列為鏈表結(jié)構(gòu)的有界隊(duì)列。
應(yīng)用場(chǎng)景:不適合并發(fā)但可能引起IO阻塞性及影響UI線程響應(yīng)的操作,如數(shù)據(jù)庫(kù)操作、文件操作等。
上述四個(gè)線程池雖然方便,但是阿里巴巴規(guī)范明確說(shuō)明不建議使用,因?yàn)榭赡軙?huì)造成內(nèi)存溢出,具體原因如下:
FixedThreadPool
和SingleThreadExecutor
:主要問題是堆積的請(qǐng)求處理隊(duì)列均采用LinkedBlockingQueue,可能會(huì)耗費(fèi)非常大的內(nèi)存,嚴(yán)重的直接導(dǎo)致內(nèi)存溢出。CachedThreadPool
和ScheduledThreadPool
:主要問題是它們的最大線程數(shù)是Integer.MAX_VALUE,可能會(huì)創(chuàng)建數(shù)量非常多的線程,嚴(yán)重的直接導(dǎo)致內(nèi)存溢出。
到此這篇關(guān)于Java線程池實(shí)現(xiàn)原理總結(jié)的文章就介紹到這了,更多相關(guān)線程池實(shí)現(xiàn)原理總結(jié)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
執(zhí)行java請(qǐng)求時(shí)導(dǎo)致在腳本執(zhí)行結(jié)束時(shí)JVM無(wú)法退出
這篇文章主要介紹了執(zhí)行java請(qǐng)求,導(dǎo)致在腳本執(zhí)行結(jié)束時(shí)JVM無(wú)法退出問題,本文通過(guò)原因分析給出解決方案,需要的朋友可以參考下2020-02-02MySQL數(shù)據(jù)文件直接通過(guò)拷貝備份與恢復(fù)的操作方法
這篇文章主要介紹了MySQL數(shù)據(jù)文件直接通過(guò)拷貝備份與恢復(fù)的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09SpringMVC返回的ResponseEntity出現(xiàn)亂碼及解決
這篇文章主要介紹了SpringMVC返回的ResponseEntity出現(xiàn)亂碼及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02springboot?靜態(tài)方法中使用@Autowired注入方式
這篇文章主要介紹了springboot?靜態(tài)方法中使用@Autowired注入方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02Java語(yǔ)言中&&與& ||與|的區(qū)別是什么
這篇文章主要介紹了Java語(yǔ)言中&&與& ||與|的區(qū)別是什么的相關(guān)資料,需要的朋友可以參考下2017-04-04淺談Map集合中g(shù)et不存在的key值,會(huì)拋出異常嗎?
這篇文章主要介紹了淺談Map集合中g(shù)et不存在的key值,會(huì)拋出異常嗎?具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09Java 實(shí)現(xiàn)Excel文檔添加超鏈接的代碼
超鏈接即內(nèi)容鏈接,通過(guò)給特定對(duì)象設(shè)置超鏈接,可實(shí)現(xiàn)載體與特定網(wǎng)頁(yè)、文件、郵件、網(wǎng)絡(luò)等的鏈接,點(diǎn)擊鏈接載體可打開鏈接目標(biāo),在文檔處理中是一種比較常用的功能,本文將介紹通過(guò)Java程序給Excel文檔添加超鏈接的方法,感興趣的朋友一起看看吧2020-02-02vue+springboot上傳文件、圖片、視頻及回顯到前端詳解
一般來(lái)說(shuō)vue可以使用axios或者fetch等ajax庫(kù)發(fā)送文件請(qǐng)求,而springboot則可以使用Spring MVC的方式來(lái)處理上傳文件請(qǐng)求,下面這篇文章主要給大家介紹了關(guān)于vue+springboot上傳文件、圖片、視頻及回顯到前端的相關(guān)資料,需要的朋友可以參考下2023-04-04