- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- 淺談Java ThreadPoolExecutor的使用
線(xiàn)程池主要由以下4個(gè)核心組件組成。
如下是線(xiàn)程池的構造方法
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; }
其中具體參數含義為:
1.corePoolSize:線(xiàn)程池中核心線(xiàn)程的數量
2.maximumPoolSize:線(xiàn)程池中最大線(xiàn)程的數量
3.keepAliveTime:當線(xiàn)程數量超過(guò)corePoolSize時(shí),空閑線(xiàn)程的存活時(shí)間
4.unit:keepAliveTime的時(shí)間單位
5.workQueue:任務(wù)隊列,被提交但尚未被執行的任務(wù)存放的地方
6.threadFactory:線(xiàn)程工廠(chǎng),用于創(chuàng )建線(xiàn)程,可使用默認的線(xiàn)程工廠(chǎng)或自定義線(xiàn)程工廠(chǎng)
7.handler:由于任務(wù)過(guò)多或其他原因導致線(xiàn)程池無(wú)法處理時(shí)的任務(wù)拒絕策略
編寫(xiě)測試類(lèi)如下:
public class ThreadPoolSerialTest { public static void main(String[] args) { //核心線(xiàn)程數 int corePoolSize = 2; //最大線(xiàn)程數 int maximumPoolSize = 4; //超過(guò)corePoolSize線(xiàn)程數量的線(xiàn)程最大空閑時(shí)間 long keepAliveTime = 2; //以秒為時(shí)間單位 TimeUnit unit = TimeUnit.SECONDS; //創(chuàng )建工作隊列,用于存放提交的等待執行任務(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)程執行時(shí)間,10s Thread.sleep(10000); System.out.println("線(xiàn)程:"+index+"運行完畢"); } 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)程池執行了6次任務(wù),恰好滿(mǎn)足maximumPoolSize
+workQueue容量
=并發(fā)執行任務(wù)數
。輸出結果如下:
大家好,我是線(xiàn)程:1
大家好,我是線(xiàn)程:2
大家好,我是線(xiàn)程:5
大家好,我是線(xiàn)程:6
線(xiàn)程:1運行完畢
大家好,我是線(xiàn)程:3
線(xiàn)程:2運行完畢
大家好,我是線(xiàn)程:4
線(xiàn)程:5運行完畢
線(xiàn)程:6運行完畢
線(xiàn)程:3運行完畢
線(xiàn)程:4運行完畢
這段輸出看似沒(méi)有規律,其實(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)程池的corePoolSize=2
,此時(shí)前兩個(gè)任務(wù)提交后就立即執行,便輸出了線(xiàn)程1 線(xiàn)程2
;
2.此時(shí)仍繼續向線(xiàn)程池提交任務(wù),線(xiàn)程池中workQueue容量=2
,被加入的任務(wù)存放到任務(wù)隊列中,即把線(xiàn)程3 線(xiàn)程4
存放到了任務(wù)隊列中;
3.任務(wù)隊列充滿(mǎn)后,仍繼續向線(xiàn)程池提交任務(wù),線(xiàn)程池的maximumPoolSize=4
,除開(kāi)核心線(xiàn)程數2個(gè)外還允許創(chuàng )建4-2
個(gè)線(xiàn)程來(lái)執行任務(wù),便輸出了線(xiàn)程5 線(xiàn)程6
線(xiàn)程:1運行完畢
大家好,我是線(xiàn)程:3
線(xiàn)程:2運行完畢
大家好,我是線(xiàn)程:4
1.線(xiàn)程:1運行完畢:表示第一個(gè)線(xiàn)程任務(wù)執行完畢了
2.大家好,我是線(xiàn)程:3:線(xiàn)程1運行完畢后,此時(shí)線(xiàn)程池中有一個(gè)空閑的線(xiàn)程,第一個(gè)進(jìn)入任務(wù)隊列中的任務(wù)第一個(gè)交給線(xiàn)程處理
3.線(xiàn)程:2運行完畢 大家好,我是線(xiàn)程:4 :和上面線(xiàn)程執行完畢,任務(wù)對列中任務(wù)執行一致
線(xiàn)程:5運行完畢
線(xiàn)程:6運行完畢
線(xiàn)程:3運行完畢
線(xiàn)程:4運行完畢
因為每一個(gè)任務(wù)的執行時(shí)間控制的是一樣的,此時(shí)輸出的內容便是先被線(xiàn)程池執行的任務(wù)先執行完畢。
線(xiàn)程池剛被創(chuàng )建時(shí),只是向系統申請一個(gè)用于執行線(xiàn)程隊列和管理線(xiàn)程池的資源。在調用execute()添加一個(gè)任務(wù)時(shí),線(xiàn)程池會(huì )按照以下流程執行任務(wù):
正在運行的線(xiàn)程數量a:a<corePoolSize
,線(xiàn)程池立即創(chuàng )建線(xiàn)程并執行任務(wù);若此時(shí)a=corePoolSize
,則任務(wù)被存放到workQueue任務(wù)隊列中,直到任務(wù)隊列被充滿(mǎn)
任務(wù)隊列workQueue已充滿(mǎn)且正在運行的線(xiàn)程數a:a<maximumPoolSize
,線(xiàn)程池立即創(chuàng )建非核心線(xiàn)程并執行任務(wù);若有任務(wù)執行完畢,該任務(wù)將被線(xiàn)程池隊列中移除,線(xiàn)程池從隊列中取先入隊的任務(wù)執行;當線(xiàn)程處于空閑狀態(tài)的時(shí)間超過(guò)keepAliveTime時(shí)間時(shí),正在運行的線(xiàn)程數acorePoolSize<a
,線(xiàn)程池停止空閑的線(xiàn)程。線(xiàn)程池將任務(wù)執行完畢后,線(xiàn)程池會(huì )收縮到corePoolSize
大小
任務(wù)隊列workQueue已充滿(mǎn)且正在運行的線(xiàn)程數a:a=maximumPoolSize
,線(xiàn)程池拒絕執行該任務(wù)并拋出RejectExecutionException異常
到此這篇關(guān)于淺談Java ThreadPoolExecutor的使用的文章就介紹到這了,更多相關(guān)Java ThreadPoolExecutor內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站