創(chuàng)建線程會(huì)產(chǎn)生系統(tǒng)開(kāi)銷(xiāo),并且每個(gè)線程會(huì)占用一定的內(nèi)存等資源,同時(shí)線程的銷(xiāo)毀也需要帶來(lái)一定的壓力。過(guò)多的線程還會(huì)帶來(lái)由于上下文切換等等的性能損耗。
使用線程池的好處:
1)提高響應(yīng)速度:通過(guò)復(fù)用線程可以消除線程創(chuàng)建銷(xiāo)毀帶來(lái)的延遲,提示響應(yīng)速度
2)降低資源消耗線程池可以統(tǒng)籌內(nèi)存和CPU的使用,避免資源使用不當(dāng),線程池會(huì)根據(jù)配置和任務(wù)數(shù)量靈活控制線程數(shù)量,不夠就創(chuàng)建,多了就回收,避免線程過(guò)多導(dǎo)致內(nèi)存溢出,過(guò)少導(dǎo)致資源浪費(fèi)
3)提高線程可管理行線程池可以統(tǒng)一管理資源,統(tǒng)一進(jìn)行分配、調(diào)優(yōu)、監(jiān)控。
一、線程池參數(shù)
1.1 線程池核心參數(shù)
1)corePoolSize
核心線程數(shù)。默認(rèn)情況核心線程會(huì)一直存活。
2)maxPoolSize
最大線程數(shù)。決定線程池最多可以創(chuàng)建多少個(gè)線程
3)KeepAliveTime+時(shí)間單位
設(shè)置線程空閑時(shí)間,當(dāng)線程空閑時(shí)間超過(guò)KeepAliveTime就會(huì)被銷(xiāo)毀。allowCoreThreadTimeOut 參數(shù)可以決定核心線程若空閑時(shí)間過(guò)長(zhǎng),是否可以被回收
4)ThreadFactory
線程工廠。用來(lái)創(chuàng)建新線程,可以對(duì)線程的屬性進(jìn)行定制,比如線程group、線程名稱(chēng)、優(yōu)先級(jí)等。
5)workQueue
存放任務(wù)的隊(duì)列,即緩沖隊(duì)列。
6)Handler
任務(wù)被拒絕時(shí)的策略
拒絕時(shí)機(jī):
- 調(diào)用shutdown等方法關(guān)閉線程池后,此時(shí)如果再向線程池提交任務(wù),則遭到拒絕
- 線程池沒(méi)有能力處理任務(wù)時(shí),即線程數(shù)達(dá)到了maxPoolSize,切workQueue已滿
1.2 線程池拒絕策略
拒絕策略統(tǒng)一實(shí)現(xiàn)java.util.concurrent.RejectedExecutionHandler
java在ThreadPoolExecutor中提供了其4中實(shí)現(xiàn):
- AbortPolicy 當(dāng)需要拒接任務(wù)時(shí),直接拋出RejectedExecutionException運(yùn)行時(shí)異常
- DiscardPolicy 當(dāng)需要拒絕任務(wù)時(shí)直接丟棄,也不會(huì)給任何通知,可能會(huì)造成數(shù)據(jù)丟失
- DiscardOldestPolicy 當(dāng)需要拒絕任務(wù)時(shí),丟棄任務(wù)隊(duì)列中最長(zhǎng)時(shí)間未被執(zhí)行的任務(wù),同樣存在數(shù)據(jù)丟失風(fēng)險(xiǎn)
- CallerRunsPolicy 當(dāng)需要拒絕任務(wù)時(shí),則將此任務(wù)交給提交該任務(wù)的線程去執(zhí)行。不會(huì)造成數(shù)據(jù)丟失,而且當(dāng)線程池滿負(fù)載時(shí),新來(lái)的任務(wù)由提交任務(wù)的線程去執(zhí)行,這樣主線程因?yàn)閳?zhí)行任務(wù)而被占用,也就減緩了提交新任務(wù)的速度,而線程池也可再次期間執(zhí)掉一部分任務(wù),騰出空間,相當(dāng)于給了線程池一個(gè)緩沖期,并且相當(dāng)于有一個(gè)負(fù)向反饋。
1.3 線程池常用阻塞隊(duì)列
- ArrayBlockingQueue
- LinkedBlockingQueue
- SynchronizedQueue
內(nèi)部沒(méi)有緩沖區(qū) - DelayedWorkQueue
三、線程池運(yùn)行過(guò)程

四、 常見(jiàn)線程池
4.1 FixedThreadPool
固定線程數(shù),無(wú)界隊(duì)列,由于無(wú)界隊(duì)列,會(huì)OOM。適用于任務(wù)數(shù)量不均勻、對(duì)內(nèi)存壓力不敏感場(chǎng)景。
4.2 CachedThreadPool
由于maximumPoolSize為Integer,MAX_VALUE,所以最終創(chuàng)建的線程數(shù)量會(huì)達(dá)到操作系統(tǒng)的上限或者導(dǎo)致內(nèi)存不足。適用于要求低延遲的短期任務(wù)場(chǎng)景
4.3 ScheduledThreadPool
適用于定時(shí)任務(wù)執(zhí)行場(chǎng)景,支持固定頻率和固定延時(shí)
4.4 SingleThreadExecutor
單線程線程池,適用于需要一部執(zhí)行但需要保證任務(wù)順序的場(chǎng)景
SingleThreadScheduledExecutor
ForkJoinPool
采用分治思想,將大任務(wù)分解成多個(gè)小任務(wù)處理,然后合并結(jié)果
//TODO ForkJoinPool 需要重點(diǎn)關(guān)注
五、線程池異常捕獲機(jī)制
總而言之,使用execute方法提交任務(wù)時(shí),異??梢酝ㄟ^(guò)線程的UncaughtExceptionHandler機(jī)制捕捉異常。
而通過(guò)submit方式則不會(huì),因?yàn)閟ubmit方法會(huì)將傳入的runnable封裝為future,而future內(nèi)部執(zhí)行時(shí),直接進(jìn)行了try catch,因而異常不會(huì)被拋出去,因?yàn)榫€程池也就感知不到異常。
https://www.cnblogs.com/ncy1/articles/11629933.html
7.4 線程數(shù)量應(yīng)該設(shè)置為多少
CPU密集型任務(wù)設(shè)置為CPU核心數(shù)的1~2倍
IO密集型任務(wù)公式:CPU核心數(shù)*(1+平均等待時(shí)間(I/O)/平均工作時(shí)間(cpu計(jì)算))