線程池知識(shí)點(diǎn)補(bǔ)充與總結(jié)

前言
最近連續(xù)三天我們都在探討線程池相關(guān)知識(shí),因?yàn)檫^(guò)程講的比較細(xì),所以花的時(shí)間也比較久,不過(guò)昨天分享完成后,這塊的內(nèi)容也就基本結(jié)束了,今天我們就花一點(diǎn)時(shí)間做一個(gè)簡(jiǎn)單的總結(jié),然后在總結(jié)之外,我們?cè)侔阎斑z漏的知識(shí)點(diǎn)補(bǔ)充下。好了,話不多說(shuō),讓我們直接開(kāi)始吧!
線程池
今天的內(nèi)容主要包括兩個(gè)方面,一個(gè)就是總結(jié),另一個(gè)就是查漏補(bǔ)缺,我們先說(shuō)線程池的總結(jié)。
總結(jié)
關(guān)于總結(jié)的內(nèi)容,我畫了一個(gè)腦圖(持續(xù)補(bǔ)充),所以總結(jié)就主要圍繞這個(gè)腦圖展開(kāi),這個(gè)腦圖各位小伙伴可以在公眾號(hào)聊天窗口輸入【線程池】獲取:

因?yàn)槭强偨Y(jié),所以這一款的內(nèi)容就不拖沓,只說(shuō)知識(shí)點(diǎn),想了解更詳細(xì)的內(nèi)容可以翻看最近三天的推送內(nèi)容。
構(gòu)造參數(shù)
線程池有7個(gè)構(gòu)造參數(shù):
corePoolSize:核心線程數(shù)maximumPoolSize:最大線程數(shù)keepAliveTime:線程存活時(shí)間TimUnit:線程存活時(shí)間的時(shí)間單位workQueue:工作隊(duì)列ThreadFactory:線程工廠RejectedExecutionHandler:拒絕策略處理器
構(gòu)造方法
線程池有四個(gè)構(gòu)造方法:
基本構(gòu)造方法:前五個(gè)參數(shù)(那天我說(shuō)就三個(gè),我是沒(méi)算存活時(shí)間和存活時(shí)間的時(shí)間單位) 工廠構(gòu)造方法:前五個(gè)參數(shù) +線程工廠策略構(gòu)造方法:前五個(gè)參數(shù) +拒絕策略處理器全套構(gòu)造方法:所有參數(shù)都有
常用方法
execute:執(zhí)行多線程任務(wù),沒(méi)有返回值submit:執(zhí)行多線程任務(wù),有返回值的,父類方法shutdown:關(guān)閉線程池
其他方法
prestartCoreThread:預(yù)啟動(dòng)一個(gè)核心線程,如果核心線程都已經(jīng)啟動(dòng)就沒(méi)啥用了prestartAllCoreThreads:預(yù)啟動(dòng)所有核心線程,如果核心線程都啟動(dòng)這個(gè)方法也一樣沒(méi)有用shutdownNow:立即關(guān)閉線程池,關(guān)于它和shutdown的區(qū)別,我們后面補(bǔ)充說(shuō)明isShutdown:線程池是否已關(guān)閉,如果執(zhí)行過(guò)shutdown或者shutdwonNow,則該方法值為trueisTerminating:線程池是否正在停止,執(zhí)行過(guò)關(guān)閉方法后,但線程池未完全停止,該方法值為trueisTerminated:線程池徹底關(guān)閉后該方法值為truepurge:移除工作隊(duì)列中所以被取消的任務(wù)remove:移除工作隊(duì)列中的任務(wù)
核心知識(shí)點(diǎn)
線程池能夠處理的最大任務(wù)數(shù) = corePoolSize + maximumPoolSize + workQueue向已經(jīng)達(dá)到最大任務(wù)處理數(shù)線程池提交新的任務(wù)時(shí),會(huì)觸發(fā) RejectedExecutionHandler的rejectedExecution方法RejectedExecutionHandler的rejectedExecution方法如果拋出RejectedExecutionException會(huì)導(dǎo)致核心線程阻塞如果不指定 RejectedExecutionHandler,系統(tǒng)會(huì)指定默認(rèn)的處理器AbortPolicy,默認(rèn)處理器會(huì)直接拋出RejectedExecutionException線程池在創(chuàng)建后是沒(méi)有線程的,線程是在 execute方法執(zhí)行后才創(chuàng)建的可以通過(guò) prestartCoreThread或者prestartAllCoreThreads方法來(lái)初始化線程池,也就就是預(yù)創(chuàng)建核心線程線程池使用完成后必須關(guān)閉,否則會(huì)阻塞后續(xù)操作 在核心線程沒(méi)有完全啟動(dòng)完,每次 execute都會(huì)創(chuàng)建新的線程線程池最大線程數(shù)只能大于等于核心線程數(shù) 當(dāng)任務(wù)數(shù)大于核心線程數(shù)+工作隊(duì)列大小時(shí),若最大線程數(shù)大于核心線程數(shù),則會(huì)繼續(xù)創(chuàng)建線程,直到線程數(shù)達(dá)到最大線程數(shù) 線程存活時(shí)間只對(duì)核心線程之外的線程資源起作用,它在工作隊(duì)列為空時(shí)起作用,延緩核心線程之外的線程資源的銷毀 線程池關(guān)閉后便再無(wú)法繼續(xù)接受任務(wù),如果關(guān)閉后繼續(xù)執(zhí)行 excute方法會(huì)調(diào)用rejectedExecution方法
補(bǔ)充知識(shí)
shutdown和shutdownNow
shutdown執(zhí)行后會(huì)等待所有已經(jīng)提交的線程執(zhí)行完成,執(zhí)行之后,只是不能再接受新的任務(wù),shutdwonNow會(huì)嘗試關(guān)閉所有正在執(zhí)行的任務(wù),同時(shí)會(huì)取消正在等待的任務(wù),會(huì)返回未執(zhí)行完成的任務(wù)。
下面是他們的內(nèi)部實(shí)現(xiàn):

prestartCoreThread和prestartAllCoreThreads
我們前面說(shuō)了,正常情況下,線程啟動(dòng)是在execute方法或者sumbit方法執(zhí)行的時(shí)候啟動(dòng)的,但是我們也可以提前啟動(dòng)核心線程池中線程。
prestartCoreThread是預(yù)啟動(dòng)一個(gè)核心線程,當(dāng)然前提條件是核心線程數(shù)未達(dá)到核心線程數(shù)上線,prestartAllCoreThreads是啟動(dòng)所有的核心線程,前提條件是一樣的。
其他補(bǔ)充內(nèi)容
其實(shí)線程池這塊至少還有三塊內(nèi)容需要補(bǔ)充,一個(gè)是工作隊(duì)列,一個(gè)是拒絕策略器,另一個(gè)就是系統(tǒng)常用的線程池的實(shí)現(xiàn)機(jī)制,但是我暫時(shí)不打算分享了,這塊的內(nèi)容看著不多,但是如果真要分享的話,至少需要分三次才能徹底搞完;
另外一個(gè)考慮的是,不能我把什么都講完,要給大家留一點(diǎn)內(nèi)容供大家自學(xué);
最后一個(gè)原因是,最近天天都是線程池,有點(diǎn)上頭,稍事休息下,畢竟周末也不能太卷了
總結(jié)
其實(shí)今天通篇就是在總結(jié),所以總結(jié)的話就沒(méi)必要多說(shuō)了,但是還是想從個(gè)人學(xué)習(xí)經(jīng)驗(yàn)這塊多叨叨兩句。
學(xué)習(xí)這件事最重要的還是要主動(dòng),要多動(dòng)手。對(duì)我來(lái)說(shuō),我之前對(duì)多線程的認(rèn)識(shí)僅僅是停留在會(huì)用,只知道一些常用的方法,但是對(duì)于它內(nèi)部的原理和實(shí)現(xiàn)機(jī)制,一直是不求甚解的,但是呢,通過(guò)最近這三四天,我現(xiàn)在已經(jīng)對(duì)線程池有了更系統(tǒng)的認(rèn)知和了解,而且也更清楚線程池實(shí)際使用的潛在問(wèn)題,以及如何避免這些問(wèn)題,這就是我學(xué)習(xí)的意義。
當(dāng)然更深遠(yuǎn)的意義是結(jié)合自己之前遇到的一些線上問(wèn)題,我發(fā)現(xiàn)原來(lái)如果我能早點(diǎn)知道這些知識(shí),那我可以少走很多彎路,這大概就是成長(zhǎng)吧——技術(shù)有了積累,眼界得到開(kāi)闊,未來(lái)才能走更遠(yuǎn)……
好了,最后希望所有小伙伴都能找到適合自己的學(xué)習(xí)之路,能夠在自己的努力下,得到自己期待的東西……周末快樂(lè)鴨!
- END -