您好,登錄后才能下訂單哦!
降低資源消耗。通過(guò)重復(fù)利用已創(chuàng)建的線程降低線程創(chuàng)建、銷毀線程造成的消耗。
提高響應(yīng)速度。當(dāng)任務(wù)到達(dá)時(shí),任務(wù)可以不需要等到線程創(chuàng)建就能立即執(zhí)行。
參數(shù) | 說(shuō)明 |
---|---|
corePoolSize | 核心線程數(shù)量,線程池維護(hù)線程的最少數(shù)量 |
maximumPoolSize | 線程池維護(hù)線程的最大數(shù)量 |
keepAliveTime | 線程池除核心線程外的其他線程的最長(zhǎng)空閑時(shí)間,超過(guò)該時(shí)間的空閑線程會(huì)被銷毀 |
unit | keepAliveTime的單位,TimeUnit中的幾個(gè)靜態(tài)屬性:NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS |
workQueue | 線程池所使用的任務(wù)緩沖隊(duì)列 |
threadFactory | 線程工廠,用于創(chuàng)建線程,一般用默認(rèn)的即可 |
handler | 線程池對(duì)拒絕任務(wù)的處理策略 |
當(dāng)線程池任務(wù)處理不過(guò)來(lái)的時(shí)候(什么時(shí)候認(rèn)為處理不過(guò)來(lái)后面描述),可以通過(guò)handler指定的策略進(jìn)行處理,ThreadPoolExecutor提供了四種策略:
可以通過(guò)實(shí)現(xiàn)RejectedExecutionHandler接口自定義處理方式。
2.1. 如果此時(shí)線程池中的數(shù)量小于corePoolSize,即使線程池中的線程都處于空閑狀態(tài),也要?jiǎng)?chuàng)建新的線程來(lái)處理被添加的任務(wù)。
2.2. 如果此時(shí)線程池中的數(shù)量等于corePoolSize,但是緩沖隊(duì)列workQueue未滿,那么任務(wù)被放入緩沖隊(duì)列。
2.3. 如果此時(shí)線程池中的數(shù)量大于等于corePoolSize,緩沖隊(duì)列workQueue滿,并且線程池中的數(shù)量小于maximumPoolSize,建新的線程來(lái)處理被添加的任務(wù)。
2.4. 如果此時(shí)線程池中的數(shù)量大于corePoolSize,緩沖隊(duì)列workQueue滿,并且線程池中的數(shù)量等于maximumPoolSize,那么通過(guò) handler所指定的策略來(lái)處理此任務(wù)。
2.5. 當(dāng)線程池中的線程數(shù)量大于 corePoolSize時(shí),如果某線程空閑時(shí)間超過(guò)keepAliveTime,線程將被終止。這樣,線程池可以動(dòng)態(tài)的調(diào)整池中的線程數(shù)。
總結(jié)即:處理任務(wù)判斷的優(yōu)先級(jí)為 核心線程corePoolSize、任務(wù)隊(duì)列workQueue、最大線程maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務(wù)。
注意:
3.1. shutdown() 不接收新任務(wù),會(huì)處理已添加任務(wù)
3.2. shutdownNow() 不接受新任務(wù),不處理已添加任務(wù),中斷正在處理的任務(wù)
4.1. ArrayBlockingQueue: 這是一個(gè)由數(shù)組實(shí)現(xiàn)的容量固定的有界阻塞隊(duì)列.
4.2. SynchronousQueue: 沒(méi)有容量,不能緩存數(shù)據(jù);每個(gè)put必須等待一個(gè)take; offer()的時(shí)候如果沒(méi)有另一個(gè)線程在poll()或者take()的話返回false。
4.3. LinkedBlockingQueue: 這是一個(gè)由單鏈表實(shí)現(xiàn)的默認(rèn)×××的阻塞隊(duì)列。LinkedBlockingQueue提供了一個(gè)可選有界的構(gòu)造函數(shù),而在未指明容量時(shí),容量默認(rèn)為Integer.MAX_VALUE。
隊(duì)列操作:
方法 | 說(shuō)明 |
---|---|
add | 增加一個(gè)元索; 如果隊(duì)列已滿,則拋出一個(gè)異常 |
remove | 移除并返回隊(duì)列頭部的元素; 如果隊(duì)列為空,則拋出一個(gè)異常 |
offer | 添加一個(gè)元素并返回true; 如果隊(duì)列已滿,則返回false |
poll | 移除并返回隊(duì)列頭部的元素; 如果隊(duì)列為空,則返回null |
put | 添加一個(gè)元素; 如果隊(duì)列滿,則阻塞 |
take | 移除并返回隊(duì)列頭部的元素; 如果隊(duì)列為空,則阻塞 |
element | 返回隊(duì)列頭部的元素; 如果隊(duì)列為空,則拋出一個(gè)異常 |
peek | 返回隊(duì)列頭部的元素; 如果隊(duì)列為空,則返回null |
1. Executors.newCachedThreadPool();
說(shuō)明: 創(chuàng)建一個(gè)可緩存線程池,如果線程池長(zhǎng)度超過(guò)處理需要,可靈活回收空閑線程,若無(wú)可回收,則新建線程.
內(nèi)部實(shí)現(xiàn):new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.SECONDS,new SynchronousQueue<runnable>());</runnable>
2. Executors.newFixedThreadPool(int);
說(shuō)明: 創(chuàng)建一個(gè)定長(zhǎng)線程池,可控制線程最大并發(fā)數(shù),超出的線程會(huì)在隊(duì)列中等待。
內(nèi)部實(shí)現(xiàn):new ThreadPoolExecutor(nThreads, nThreads,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<runnable>());</runnable>
3. Executors.newSingleThreadExecutor();
說(shuō)明:創(chuàng)建一個(gè)單線程化的線程池,它只會(huì)用唯一的工作線程來(lái)執(zhí)行任務(wù),保證所有任務(wù)按照順序執(zhí)行。
內(nèi)部實(shí)現(xiàn):new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<runnable>())</runnable>
4. Executors.newScheduledThreadPool(int);
說(shuō)明:創(chuàng)建一個(gè)定長(zhǎng)線程池,支持定時(shí)及周期性任務(wù)執(zhí)行。
內(nèi)部實(shí)現(xiàn):new ScheduledThreadPoolExecutor(corePoolSize)
【附】阿里巴巴Java開(kāi)發(fā)手冊(cè)中對(duì)線程池的使用規(guī)范
【強(qiáng)制】創(chuàng)建線程或線程池時(shí)請(qǐng)指定有意義的線程名稱,方便出錯(cuò)時(shí)回溯。
正例:
public class TimerTaskThread extends Thread {
public TimerTaskThread(){
super.setName("TimerTaskThread");
...
}
}
【強(qiáng)制】線程資源必須通過(guò)線程池提供,不允許在應(yīng)用中自行顯式創(chuàng)建線程。
說(shuō)明: 使用線程池的好處是減少在創(chuàng)建和銷毀線程上所花的時(shí)間以及系統(tǒng)資源的開(kāi)銷,解決資
源不足的問(wèn)題。如果不使用線程池,有可能造成系統(tǒng)創(chuàng)建大量同類線程而導(dǎo)致消耗完內(nèi)存或者
“過(guò)度切換”的問(wèn)題。
說(shuō)明: Executors 返回的線程池對(duì)象的弊端如下:
1) FixedThreadPool 和 SingleThreadPool:
允許的請(qǐng)求隊(duì)列長(zhǎng)度為 Integer.MAX_VALUE,可能會(huì)堆積大量的請(qǐng)求,從而導(dǎo)致 OOM。
2) CachedThreadPool 和 ScheduledThreadPool:
允許的創(chuàng)建線程數(shù)量為 Integer.MAX_VALUE, 可能會(huì)創(chuàng)建大量的線程,從而導(dǎo)致 OOM。
ThreadPoolExecutor通過(guò)幾個(gè)核心參數(shù)來(lái)定義不同類型的線程池,適用于不同的使用場(chǎng)景;其中在任務(wù)提交時(shí),會(huì)依次判斷corePoolSize, workQueque, 及maximumPoolSize,不同的狀態(tài)不同的處理。技術(shù)領(lǐng)域水太深,如果不是日常使用,基本一段時(shí)間后某些知識(shí)點(diǎn)就忘的差不多了,因此階段性地回顧與總結(jié),對(duì)夯實(shí)自己的技術(shù)基礎(chǔ)很有必要。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。