淺談Java ThreadPoolExecutor的使用
線(xiàn)程池主要由以下4個(gè)核心組件組成。
線(xiàn)程池管理器:用于創(chuàng)建并管理線(xiàn)程池 工作線(xiàn)程:線(xiàn)程池中執(zhí)行具體任務(wù)的線(xiàn)程 任務(wù)接口:用于定義工作線(xiàn)程的調(diào)度和執(zhí)行策略,只有線(xiàn)程實(shí)現(xiàn)了該接口,線(xiàn)程中的任務(wù)才能被線(xiàn)程池調(diào)度 任務(wù)隊(duì)列:放待處理的任務(wù),新的任務(wù)將會(huì)不斷被加入隊(duì)列中,執(zhí)行完成的任務(wù)將從隊(duì)列中移除如下是線(xiàn)程池的構(gòu)造方法
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException();if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException();this.acc = System.getSecurityManager() == null ?null :AccessController.getContext();this.corePoolSize = corePoolSize;this.maximumPoolSize = maximumPoolSize;this.workQueue = workQueue;this.keepAliveTime = unit.toNanos(keepAliveTime);this.threadFactory = threadFactory;this.handler = handler;}
其中具體參數(shù)含義為:
1.corePoolSize:線(xiàn)程池中核心線(xiàn)程的數(shù)量
2.maximumPoolSize:線(xiàn)程池中最大線(xiàn)程的數(shù)量
3.keepAliveTime:當(dāng)線(xiàn)程數(shù)量超過(guò)corePoolSize時(shí),空閑線(xiàn)程的存活時(shí)間
4.unit:keepAliveTime的時(shí)間單位
5.workQueue:任務(wù)隊(duì)列,被提交但尚未被執(zhí)行的任務(wù)存放的地方
6.threadFactory:線(xiàn)程工廠(chǎng),用于創(chuàng)建線(xiàn)程,可使用默認(rèn)的線(xiàn)程工廠(chǎng)或自定義線(xiàn)程工廠(chǎng)
7.handler:由于任務(wù)過(guò)多或其他原因?qū)е戮€(xiàn)程池?zé)o法處理時(shí)的任務(wù)拒絕策略
三、構(gòu)造函數(shù)參數(shù)解析編寫(xiě)測(cè)試類(lèi)如下:
public class ThreadPoolSerialTest { public static void main(String[] args) {//核心線(xiàn)程數(shù)int corePoolSize = 2;//最大線(xiàn)程數(shù)int maximumPoolSize = 4;//超過(guò)corePoolSize線(xiàn)程數(shù)量的線(xiàn)程最大空閑時(shí)間long keepAliveTime = 2;//以秒為時(shí)間單位TimeUnit unit = TimeUnit.SECONDS;//創(chuàng)建工作隊(duì)列,用于存放提交的等待執(zhí)行任務(wù)BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);ThreadPoolExecutor threadPoolExecutor = null;try { // 1.創(chuàng)建線(xiàn)程池 threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, new ThreadPoolExecutor.AbortPolicy()); // 2.循環(huán)提交任務(wù) for (int i = 0; i < 6; i++) {//提交任務(wù)的索引final int index = (i+1);threadPoolExecutor.submit(()->{ //線(xiàn)程打印輸出 System.out.println('大家好,我是線(xiàn)程:'+index); try {//模擬線(xiàn)程執(zhí)行時(shí)間,10sThread.sleep(10000);System.out.println('線(xiàn)程:'+index+'運(yùn)行完畢'); } catch (InterruptedException e) {e.printStackTrace(); }});//每個(gè)任務(wù)提交后休眠500ms再提交下一個(gè)任務(wù),用于保證提交順序Thread.sleep(500); }} catch (InterruptedException e) { e.printStackTrace();} finally { // 3.關(guān)閉線(xiàn)程池 threadPoolExecutor.shutdown();} }}
其中循環(huán)了6次,讓線(xiàn)程池執(zhí)行了6次任務(wù),恰好滿(mǎn)足maximumPoolSize+workQueue容量=并發(fā)執(zhí)行任務(wù)數(shù)。輸出結(jié)果如下:
大家好,我是線(xiàn)程:1大家好,我是線(xiàn)程:2大家好,我是線(xiàn)程:5大家好,我是線(xiàn)程:6線(xiàn)程:1運(yùn)行完畢大家好,我是線(xiàn)程:3線(xiàn)程:2運(yùn)行完畢大家好,我是線(xiàn)程:4線(xiàn)程:5運(yùn)行完畢線(xiàn)程:6運(yùn)行完畢線(xiàn)程:3運(yùn)行完畢線(xiàn)程:4運(yùn)行完畢
這段輸出看似沒(méi)有規(guī)律,其實(shí)這里輸出完全是由線(xiàn)程池控制的;下面就來(lái)分行解析輸出:
大家好,我是線(xiàn)程:1 大家好,我是線(xiàn)程:2大家好,我是線(xiàn)程:5大家好,我是線(xiàn)程:6
1.全新線(xiàn)程池被創(chuàng)建后,有Runnable或CallBack接口的實(shí)現(xiàn)被提交給線(xiàn)程池執(zhí)行;線(xiàn)程池的corePoolSize=2,此時(shí)前兩個(gè)任務(wù)提交后就立即執(zhí)行,便輸出了線(xiàn)程1 線(xiàn)程2;
2.此時(shí)仍繼續(xù)向線(xiàn)程池提交任務(wù),線(xiàn)程池中workQueue容量=2,被加入的任務(wù)存放到任務(wù)隊(duì)列中,即把線(xiàn)程3 線(xiàn)程4存放到了任務(wù)隊(duì)列中;
3.任務(wù)隊(duì)列充滿(mǎn)后,仍繼續(xù)向線(xiàn)程池提交任務(wù),線(xiàn)程池的maximumPoolSize=4,除開(kāi)核心線(xiàn)程數(shù)2個(gè)外還允許創(chuàng)建4-2個(gè)線(xiàn)程來(lái)執(zhí)行任務(wù),便輸出了線(xiàn)程5 線(xiàn)程6
線(xiàn)程:1運(yùn)行完畢大家好,我是線(xiàn)程:3線(xiàn)程:2運(yùn)行完畢大家好,我是線(xiàn)程:4
1.線(xiàn)程:1運(yùn)行完畢:表示第一個(gè)線(xiàn)程任務(wù)執(zhí)行完畢了
2.大家好,我是線(xiàn)程:3:線(xiàn)程1運(yùn)行完畢后,此時(shí)線(xiàn)程池中有一個(gè)空閑的線(xiàn)程,第一個(gè)進(jìn)入任務(wù)隊(duì)列中的任務(wù)第一個(gè)交給線(xiàn)程處理
3.線(xiàn)程:2運(yùn)行完畢 大家好,我是線(xiàn)程:4 :和上面線(xiàn)程執(zhí)行完畢,任務(wù)對(duì)列中任務(wù)執(zhí)行一致
線(xiàn)程:5運(yùn)行完畢線(xiàn)程:6運(yùn)行完畢線(xiàn)程:3運(yùn)行完畢線(xiàn)程:4運(yùn)行完畢
因?yàn)槊恳粋€(gè)任務(wù)的執(zhí)行時(shí)間控制的是一樣的,此時(shí)輸出的內(nèi)容便是先被線(xiàn)程池執(zhí)行的任務(wù)先執(zhí)行完畢。
四、總結(jié)線(xiàn)程池剛被創(chuàng)建時(shí),只是向系統(tǒng)申請(qǐng)一個(gè)用于執(zhí)行線(xiàn)程隊(duì)列和管理線(xiàn)程池的資源。在調(diào)用execute()添加一個(gè)任務(wù)時(shí),線(xiàn)程池會(huì)按照以下流程執(zhí)行任務(wù):
正在運(yùn)行的線(xiàn)程數(shù)量a:a<corePoolSize,線(xiàn)程池立即創(chuàng)建線(xiàn)程并執(zhí)行任務(wù);若此時(shí)a=corePoolSize,則任務(wù)被存放到workQueue任務(wù)隊(duì)列中,直到任務(wù)隊(duì)列被充滿(mǎn)
任務(wù)隊(duì)列workQueue已充滿(mǎn)且正在運(yùn)行的線(xiàn)程數(shù)a:a<maximumPoolSize,線(xiàn)程池立即創(chuàng)建非核心線(xiàn)程并執(zhí)行任務(wù);若有任務(wù)執(zhí)行完畢,該任務(wù)將被線(xiàn)程池隊(duì)列中移除,線(xiàn)程池從隊(duì)列中取先入隊(duì)的任務(wù)執(zhí)行;當(dāng)線(xiàn)程處于空閑狀態(tài)的時(shí)間超過(guò)keepAliveTime時(shí)間時(shí),正在運(yùn)行的線(xiàn)程數(shù)acorePoolSize<a,線(xiàn)程池停止空閑的線(xiàn)程。線(xiàn)程池將任務(wù)執(zhí)行完畢后,線(xiàn)程池會(huì)收縮到corePoolSize大小
任務(wù)隊(duì)列workQueue已充滿(mǎn)且正在運(yùn)行的線(xiàn)程數(shù)a:a=maximumPoolSize,線(xiàn)程池拒絕執(zhí)行該任務(wù)并拋出RejectExecutionException異常
到此這篇關(guān)于淺談Java ThreadPoolExecutor的使用的文章就介紹到這了,更多相關(guān)Java ThreadPoolExecutor內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
