1.什么是線程池
(1)管理線程的池子
(2)管理線程,避免新增線程和銷毀線程的資源消耗
(3)提高響應(yīng)速度
(4)重復(fù)利用線程
2.線程池的創(chuàng)建
線程池可以通過ThreadPoolExecutor來創(chuàng)建
(1)核心參數(shù)
corePoolSize: 線程池核心線程數(shù)最大值
maximumPoolSize: 線程池最大線程數(shù)大小
keepAliveTime: 線程池中非核心線程空閑的存活時(shí)間大小
unit: 線程空閑存活時(shí)間單位
workQueue: 存放任務(wù)的阻塞隊(duì)列
threadFactory: 用于設(shè)置創(chuàng)建線程的工廠兽泣,可以給創(chuàng)建的線程設(shè)置有意義的名字轧叽,可方便排查問題玫镐。
handler: 線城池的飽和策略事件司澎,主要有四種類型挪鹏。
3.線程池執(zhí)行流程
(1)提交一個(gè)任務(wù)沉衣,核心線程先去執(zhí)行。
(2)如果核心線程數(shù)(corePoolSize)已滿锣夹,那會(huì)把任務(wù)放入阻塞隊(duì)列。排隊(duì)等待執(zhí)行苏潜。
(3)當(dāng)核心線程數(shù)已滿(corePoolSize)银萍,并且阻塞隊(duì)列也沒有位置了。那會(huì)先判斷是否超過最大線程數(shù)(maximumPoolSize)恤左,如果沒有則調(diào)用非核心線程執(zhí)行任務(wù)贴唇。
(4)如果超過最大線程數(shù)(maximumPoolSize),則采取拒絕策略飞袋。
4.四種拒絕策略
(1)AbortPolicy(拋出一個(gè)異常戳气,默認(rèn)的)
(2)DiscardPolicy(直接丟棄任務(wù))
(3)DiscardOldestPolicy(丟棄隊(duì)列里最老的任務(wù),將當(dāng)前這個(gè)任務(wù)繼續(xù)提交給線程池)
(4)CallerRunsPolicy(交給線程池調(diào)用所在的線程進(jìn)行處理)
5.線程池的異常處理
(1)try...catch捕獲
(2)submit執(zhí)行的任務(wù)巧鸭,可以通過Future對(duì)象的get方法接收拋出的異常瓶您,再進(jìn)行處理。
(3)為工作者線程設(shè)置UncaughtExceptionHandler,在uncaughtException方法中處理異常呀袱。
(4)重寫ThreadPoolExecutor的afterExecute方法贸毕,處理傳遞的異常引用
6.線程池的工作隊(duì)列
(1)ArrayBlockingQueue(有界隊(duì)列)是一個(gè)用數(shù)組實(shí)現(xiàn)的有界阻塞隊(duì)列,按FIFO排序量夜赵。
(2)LinkedBlockingQueue(可設(shè)置容量隊(duì)列)基于鏈表結(jié)構(gòu)的阻塞隊(duì)列明棍,按FIFO排序任務(wù),容量可以選擇進(jìn)行設(shè)置寇僧,不設(shè)置的話摊腋,將是一個(gè)無邊界的阻塞隊(duì)列,最大長(zhǎng)度為Integer.MAX_VALUE嘁傀,吞吐量通常要高于ArrayBlockingQuene兴蒸;newFixedThreadPool線程池使用了這個(gè)隊(duì)列
(3)DelayQueue(延遲隊(duì)列)是一個(gè)任務(wù)定時(shí)周期的延遲執(zhí)行的隊(duì)列。根據(jù)指定的執(zhí)行時(shí)間從小到大排序心包,否則根據(jù)插入到隊(duì)列的先后排序类咧。newScheduledThreadPool線程池使用了這個(gè)隊(duì)列。
(4)PriorityBlockingQueue(優(yōu)先級(jí)隊(duì)列)是具有優(yōu)先級(jí)的無界阻塞隊(duì)列蟹腾;
(5)SynchronousQueue(同步隊(duì)列)一個(gè)不存儲(chǔ)元素的阻塞隊(duì)列痕惋,每個(gè)插入操作必須等到另一個(gè)線程調(diào)用移除操作,否則插入操作一直處于阻塞狀態(tài)娃殖,吞吐量通常要高于LinkedBlockingQuene值戳,newCachedThreadPool線程池使用了這個(gè)隊(duì)列。
7.常用線程池
(1)newFixedThreadPool (固定數(shù)目線程的線程池)
- 核心線程數(shù)和最大線程數(shù)一樣
- 沒有非核心線程數(shù)的空閑存活時(shí)間(keepAliveTime為0)
- 阻塞隊(duì)列為無邊界隊(duì)列LinkedBlockingQueue
工作機(jī)制:
- 提交任務(wù)
- 如果線程數(shù)少于核心線程炉爆,創(chuàng)建核心線程執(zhí)行任務(wù)
- 如果線程數(shù)等于核心線程堕虹,把任務(wù)添加到LinkedBlockingQueue阻塞隊(duì)列
- 如果線程執(zhí)行完任務(wù),去阻塞隊(duì)列取任務(wù)芬首,繼續(xù)執(zhí)行赴捞。
使用場(chǎng)景:
FixedThreadPool 適用于處理CPU密集型的任務(wù),確保CPU在長(zhǎng)期被工作線程使用的情況下郁稍,盡可能的少的分配線程赦政,即適用執(zhí)行長(zhǎng)期的任務(wù)。
(2)newCachedThreadPool(可緩存線程的線程池)
- 核心線程數(shù)為0
- 最大線程數(shù)為Integer.MAX_VALUE
- 阻塞隊(duì)列為同步阻塞隊(duì)列SynchronousQueue
- 非核心線程空閑存活時(shí)間為60秒(keepAliveTime為60秒)
工作機(jī)制:
- 提交任務(wù)
- 因?yàn)闆]有核心線程耀怜,所以任務(wù)直接加到SynchronousQueue隊(duì)列恢着。
- 判斷是否有空閑線程,如果有财破,就去取出任務(wù)執(zhí)行掰派。
- 如果沒有空閑線程,就新建一個(gè)線程執(zhí)行左痢。
- 執(zhí)行完任務(wù)的線程靡羡,還可以存活60秒系洛,如果在這期間,接到任務(wù)亿眠,可以繼續(xù)活下去碎罚;否則,被銷毀纳像。
使用場(chǎng)景:
用于并發(fā)執(zhí)行大量短期的小任務(wù)
(3)newSingleThreadExecutor(單線程的線程池)
- 核心線程數(shù)為1
- 最大線程數(shù)也為1
- 阻塞隊(duì)列是LinkedBlockingQueue
- keepAliveTime為0
工作機(jī)制:
- 提交任務(wù)
- 線程池是否有一條線程在荆烈,如果沒有,新建線程執(zhí)行任務(wù)
- 如果有竟趾,講任務(wù)加到阻塞隊(duì)列
- 當(dāng)前的唯一線程憔购,從隊(duì)列取任務(wù),執(zhí)行完一個(gè)岔帽,再繼續(xù)取玫鸟,一個(gè)人(一條線程)夜以繼日地干活
使用場(chǎng)景:
適用于串行執(zhí)行任務(wù)的場(chǎng)景,一個(gè)任務(wù)一個(gè)任務(wù)地執(zhí)行犀勒。
(4)newScheduledThreadPool(定時(shí)及周期執(zhí)行的線程池)
- 最大線程數(shù)為Integer.MAX_VALUE
- 阻塞隊(duì)列是DelayedWorkQueue
- keepAliveTime為0
- scheduleAtFixedRate() :按某種速率周期執(zhí)行
- scheduleWithFixedDelay():在某個(gè)延遲后執(zhí)行
工作機(jī)制
- 添加一個(gè)任務(wù)
- 線程池中的線程從 DelayQueue 中取任務(wù)
- 線程從 DelayQueue 中獲取 time 大于等于當(dāng)前時(shí)間的task
- 執(zhí)行完后修改這個(gè) task 的 time 為下次被執(zhí)行的時(shí)間
- 這個(gè) task 放回DelayQueue隊(duì)列中
使用場(chǎng)景:
周期性執(zhí)行任務(wù)的場(chǎng)景屎飘,需要限制線程數(shù)量的場(chǎng)景
8.線程池狀態(tài)
RUNNING
- 該狀態(tài)的線程池會(huì)接收新任務(wù),并處理阻塞隊(duì)列中的任務(wù);
- 調(diào)用線程池的shutdown()方法贾费,可以切換到SHUTDOWN狀態(tài);
- 調(diào)用線程池的shutdownNow()方法钦购,可以切換到STOP狀態(tài);
SHUTDOWN
- 該狀態(tài)的線程池不會(huì)接收新任務(wù),但會(huì)處理阻塞隊(duì)列中的任務(wù)褂萧;
- 隊(duì)列為空押桃,并且線程池中執(zhí)行的任務(wù)也為空,進(jìn)入TIDYING狀態(tài);
STOP
- 該狀態(tài)的線程不會(huì)接收新任務(wù),也不會(huì)處理阻塞隊(duì)列中的任務(wù)导犹,而且會(huì)中斷正在運(yùn)行的任務(wù)唱凯;
- 線程池中執(zhí)行的任務(wù)為空,進(jìn)入TIDYING狀態(tài);
TIDYING
- 該狀態(tài)表明所有的任務(wù)已經(jīng)運(yùn)行終止,記錄的任務(wù)數(shù)量為0谎痢。
- terminated()執(zhí)行完畢磕昼,進(jìn)入TERMINATED狀態(tài)
TERMINATED
- 該狀態(tài)表示線程池徹底終止
轉(zhuǎn)載與
作者:撿田螺的小男孩
鏈接:https://juejin.cn/post/6844903889678893063
來源:掘金