新聞中心
這篇文章主要講解了“什么是線程池”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“什么是線程池”吧!
創(chuàng)新互聯(lián)建站長期為1000多家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為東興企業(yè)提供專業(yè)的成都做網(wǎng)站、成都網(wǎng)站建設(shè),東興網(wǎng)站改版等技術(shù)服務(wù)。擁有十年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。
1、線程池的核心類:ThreadPoolExecutor
1.1-類圖
(I:代表接口,C:代表實(shí)現(xiàn)類)I:Executor I:ExecutorService C:AbstractExecutorService C:ThreadPoolExecutor
該類的主要構(gòu)造函數(shù)如下:
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueueworkQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
1.2-參數(shù)詳解:
corePoolSize:核心線程池的大小。如果核心線程池有空閑位置,新的任務(wù)進(jìn)來就會(huì)被核心線程池新建一個(gè)線程執(zhí)行,執(zhí)行完畢后不會(huì)銷毀線程,線程會(huì)進(jìn)入緩存隊(duì)列等待再次被運(yùn)行。
maximunPoolSize:最大的線程數(shù)量。如果核心線程池和緩存隊(duì)列都已經(jīng)滿了,新的任務(wù)進(jìn)來就會(huì)創(chuàng)建新的線程來執(zhí)行。但是數(shù)量不能超過maximunPoolSize,否側(cè)會(huì)采取拒絕接受任務(wù)策略,我們下面會(huì)具體分析。
keepAliveTime:非核心線程能夠空閑的最長時(shí)間,超過時(shí)間,線程終止。這個(gè)參數(shù)默認(rèn)只有在線程數(shù)量超過核心線程池大小時(shí)才會(huì)起作用。只要線程數(shù)量不超過核心線程大小,就不會(huì)起作用。
unit:時(shí)間單位,和keepAliveTime配合使用。
workQueue: 緩存隊(duì)列,用來存放等待被執(zhí)行的任務(wù),有以下取值:
1、ArrayBlockingQueue; 有界阻塞隊(duì)列,詳見文章:ArrayBlockingQueue詳解
2、LinkedBlockingQueue; 無界阻塞隊(duì)列,詳見文章:LinkedBlockingQueue詳解
3、SynchronousQueue; 無緩沖阻塞隊(duì)列 ,詳見文章:SynchronousQueue詳解threadFactory:線程工廠,用來創(chuàng)建線程,默認(rèn)new Executors.DefaultThreadFactory();
handler: 線程拒絕策略。當(dāng)創(chuàng)建的線程超出maximumPoolSize值,且緩沖隊(duì)列已滿時(shí),對(duì)新提交任務(wù)的處理策略,有以下4種取值,我們結(jié)合代碼分析
1、ThreadPoolExecutor.AbortPolicy 無視任務(wù)(也就是丟棄任務(wù)),并通過拋異常告知調(diào)用者“我拒絕接收新任務(wù)”public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { //這里直接拋出異常,可理解為:無視任務(wù)(也就是丟棄任務(wù)),并通過拋異常告知調(diào)用者“我拒絕接收新任務(wù)” throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); }
2、ThreadPoolExecutor.DiscardPolicy:也是丟棄任務(wù),但是不做任何處理。
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { //這里是空實(shí)現(xiàn),也就是丟棄任務(wù),不作任何的處理 //這會(huì)導(dǎo)致:雖然此策略被觸發(fā),但調(diào)用者根本不知道它提交進(jìn)來的任務(wù),最終到底有沒有被執(zhí)行 }
3、ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊(duì)列最前面的任務(wù),嘗試執(zhí)行新任務(wù)。
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { //判斷線程池是否被關(guān)閉了 e.getQueue().poll();//丟棄隊(duì)列最前面的任務(wù) e.execute(r); //嘗試執(zhí)行新任務(wù) } }
4、ThreadPoolExecutor.CallerRunsPolicy:由調(diào)用線程處理該任務(wù)
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { //判斷線程池是否被關(guān)閉了 r.run(); //調(diào)用線程直接調(diào)用run()方法,執(zhí)行其代碼邏輯 } }
1.3-Executors工廠類
基于ThreadPoolExecutor 的構(gòu)造參數(shù)如此之多,JDK為我們提供了Executors類,通過它我們可以簡單的創(chuàng)建出四種類型的線程池,一般場景下夠用了。
1.3.1、固定大小線程池
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor( nThreads, // corePoolSize nThreads,// maximumPoolSize 0L, TimeUnit.MILLISECONDS,// keepAliveTime=0秒 new LinkedBlockingQueue()// 利用無界阻塞隊(duì)列 ); }
參數(shù):corePoolSize = 固定值,maximumPoolSize = 固定值,keepAliveTime = 0秒 ,workQueue = LinkedBlockingQueue 無界阻塞隊(duì)列
分析:
1、corePoolSize 和 maximumPoolSize 都為 nThreads 一個(gè)固定值,說明此線程池中都是核心線程,keepAliveTime為非核心線程空閑時(shí)間,該線程池中不存在非核心線程,所以參數(shù)keepAliveTime在此處無效;
2、new LinkedBlockingQueue
3、缺點(diǎn):因?yàn)橛玫氖菬o界隊(duì)列,所以當(dāng) nThreads 個(gè)線程一直被占用的情況下,同時(shí)又不斷的有新任務(wù)進(jìn)來,就有可能導(dǎo)致OOM問題;
1.3.2、單個(gè)線程的線程池
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, // corePoolSize,maximumPoolSize 0L, TimeUnit.MILLISECONDS,// keepAliveTime=0秒 new LinkedBlockingQueue())// 利用無界阻塞隊(duì)列 ); }
參數(shù):corePoolSize = 1,maximumPoolSize = 1,keepAliveTime = 0秒 ,workQueue = LinkedBlockingQueue 無界阻塞隊(duì)列
分析:
1、corePoolSize 和 maximumPoolSize 都為1,此線程池只有一個(gè)核心線程,同上,參數(shù)keepAliveTime在此處無效;
2、new LinkedBlockingQueue
3、缺點(diǎn):因?yàn)橛玫氖菬o界隊(duì)列,所以當(dāng)核心線程一直被占用的情況下,同時(shí)又不斷的有新任務(wù)進(jìn)來,就有可能導(dǎo)致OOM問題;
4、有沒有注意到,這里為什么用了一個(gè)FinalizableDelegatedExecutorService類呢?
見文章:關(guān)于newSingleThreadExecutor中的FinalizableDelegatedExecutorService源碼分析
1.3.3、緩存線程池
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE,// corePoolSize,maximumPoolSize 60L, TimeUnit.SECONDS,// keepAliveTime=60秒 new SynchronousQueue());// 同步阻塞隊(duì)列 }
參數(shù):corePoolSize = 0,maximumPoolSize = 無限大,keepAliveTime = 60秒(重要) ,workQueue = SynchronousQueue 無緩沖阻塞隊(duì)列
分析:一個(gè)可以根據(jù)需要?jiǎng)?chuàng)建線程的線程池,此線程池中所有線程都為非核心線程,且最大空閑時(shí)間為60秒,最多可以創(chuàng)建Integer.MAX_VALUE 個(gè)線程(2^31次方,21億多,可以視為無限);SynchronousQueue 為無緩沖阻塞隊(duì)列,也就是此隊(duì)列里不會(huì)緩沖新的任務(wù),有新任務(wù)進(jìn)來時(shí),如果無空閑線程,就會(huì)新創(chuàng)建一個(gè)線程;如果有空閑線程,就會(huì)使用空閑線程;所以此線程池適合執(zhí)行一些執(zhí)行周期短的任務(wù)。
感謝各位的閱讀,以上就是“什么是線程池”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)什么是線程池這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
網(wǎng)頁題目:什么是線程池
文章起源:http://www.dlmjj.cn/article/jdjhic.html