這篇文章主要講解了“java線程池的工作原理”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“java線程池的工作原理”吧!
公司主營業(yè)務(wù):網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出龍游免費做網(wǎng)站回饋大家。
一、線程池創(chuàng)建
先看一下ThreadPoolExecutor參數(shù)最全的構(gòu)造方法:
①corePoolSize:線程池的核心線程數(shù),說白了就是,即便是線程池里沒有任何任務(wù),也會有corePoolSize個線程在候著等任務(wù)。
②maximumPoolSize:最大線程數(shù),不管你提交多少任務(wù),線程池里最多工作線程數(shù)就是maximumPoolSize。
③keepAliveTime:線程的存活時間。當(dāng)線程池里的線程數(shù)大于corePoolSize時,如果等了keepAliveTime時長還沒有任務(wù)可執(zhí)行,則線程退出。
⑤unit:這個用來指定keepAliveTime的單位,比如秒:TimeUnit.SECONDS。
⑥workQueue:一個阻塞隊列,提交的任務(wù)將會被放到這個隊列里。
⑦threadFactory:線程工廠,用來創(chuàng)建線程,主要是為了給線程起名字,默認(rèn)工廠的線程名字:pool-1-thread-3。
⑧handler:拒絕策略,當(dāng)線程池里線程被耗盡,且隊列也滿了的時候會調(diào)用。
以上就是創(chuàng)建線程池時用到的參數(shù),面試中經(jīng)常會有面試官問道這個問題。
二、線程池執(zhí)行流程
這里用一個圖來說明線程池的執(zhí)行流程
任務(wù)被提交到線程池,會先判斷當(dāng)前線程數(shù)量是否小于corePoolSize,如果小于則創(chuàng)建線程來執(zhí)行提交的任務(wù),否則將任務(wù)放入workQueue隊列,如果workQueue滿了,則判斷當(dāng)前線程數(shù)量是否小于maximumPoolSize,如果小于則創(chuàng)建線程執(zhí)行任務(wù),否則就會調(diào)用handler,以表示線程池拒絕接收任務(wù)。
這里以jdk1.8.0_111的源代碼為例,看一下具體實現(xiàn)。
1、先看一下線程池的executor方法
①:判斷當(dāng)前活躍線程數(shù)是否小于corePoolSize,如果小于,則調(diào)用addWorker創(chuàng)建線程執(zhí)行任務(wù)
②:如果不小于corePoolSize,則將任務(wù)添加到workQueue隊列。
③:如果放入workQueue失敗,則創(chuàng)建線程執(zhí)行任務(wù),如果這時創(chuàng)建線程失敗(當(dāng)前線程數(shù)不小于maximumPoolSize時),就會調(diào)用reject(內(nèi)部調(diào)用handler)拒絕接受任務(wù)。
2、再看下addWorker的方法實現(xiàn)
這塊代碼是在創(chuàng)建非核心線程時,即core等于false。判斷當(dāng)前線程數(shù)是否大于等于maximumPoolSize,如果大于等于則返回false,即上邊說到的③中創(chuàng)建線程失敗的情況。
addWorker方法的下半部分:
①創(chuàng)建Worker對象,同時也會實例化一個Thread對象。
②啟動啟動這個線程
3、再到Worker里看看其實現(xiàn)
可以看到在創(chuàng)建Worker時會調(diào)用threadFactory來創(chuàng)建一個線程。上邊的②中啟動一個線程就會觸發(fā)Worker的run方法被線程調(diào)用。
4、接下來咱們看看runWorker方法的邏輯
線程調(diào)用runWoker,會while循環(huán)調(diào)用getTask方法從workerQueue里讀取任務(wù),然后執(zhí)行任務(wù)。只要getTask方法不返回null,此線程就不會退出。
5、最后在看看getTask方法實現(xiàn)
①咱們先不管allowCoreThreadTimeOut,這個變量默認(rèn)值是false。wc>corePoolSize則是判斷當(dāng)前線程數(shù)是否大于corePoolSize。
②如果當(dāng)前線程數(shù)大于corePoolSize,則會調(diào)用workQueue的poll方法獲取任務(wù),超時時間是keepAliveTime。如果超過keepAliveTime時長,poll返回了null,上邊提到的while循序就會退出,線程也就執(zhí)行完了。
如果當(dāng)前線程數(shù)小于corePoolSize,則會調(diào)用workQueue的take方法阻塞在當(dāng)前。
感謝各位的閱讀,以上就是“java線程池的工作原理”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對java線程池的工作原理這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!