詳解Java線程池的使用及工作原理
一、什么是線程池?
線程池是一種用于實(shí)現(xiàn)計(jì)算機(jī)程序并發(fā)執(zhí)行的軟件設(shè)計(jì)模式。線程池維護(hù)多個(gè)線程,等待由調(diào)度程序分配任務(wù)以并發(fā)執(zhí)行,該模型提高了性能,并避免了由于為短期任務(wù)頻繁創(chuàng)建和銷毀線程而導(dǎo)致的執(zhí)行延遲。
二、線程池要解決什么問(wèn)題?
說(shuō)到線程池就一定要從線程的生命周期講起。
從圖中可以了解無(wú)論任務(wù)執(zhí)行多久,每個(gè)線程都要經(jīng)歷從生到死的狀態(tài)。而使用線程池就是為了避免線程的重復(fù)創(chuàng)建,從而節(jié)省了線程的New
至Runnable
, Running
至Terminated
的時(shí)間;同時(shí)也會(huì)復(fù)用線程,最小化的節(jié)省系統(tǒng)資源,于此同時(shí)提高了響應(yīng)速度。
三、線程池的使用
線程池的創(chuàng)建
使用ThreadPoolExecutor
并配置7個(gè)參數(shù)完成線程池的創(chuàng)建
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
- corePoolSize:線程池中核心線程的最大值
- maximumPoolSize:線程池中最大線程數(shù)
- keepAliveTime:非核心線程空閑的存活時(shí)間大小
- unit:keepAliveTime的單位,常用的有秒、分鐘、小時(shí)等
- workQueue:阻塞隊(duì)列類型
- threadFactory:線程工廠,用于配置線程的名稱,是否為守護(hù)線程等
- handler:線程池的拒絕策略
四、常用阻塞隊(duì)列
ArrayBlockingQueue
底層基于數(shù)組的實(shí)現(xiàn)的有界阻塞隊(duì)列
LinkedBlockingQueue
底層基于單鏈表的阻塞隊(duì)列,可配置容量,不配置容量默認(rèn)為Integer.MAX_VALUE
五、線程工廠
在《阿里巴巴Java開(kāi)發(fā)手冊(cè)》中強(qiáng)制要求指定線程的名稱
由于工作是使用hutool比較多,里面也包含對(duì)ThreadFactory
的封裝,可以很方便的指定名稱
ThreadFactory threadFactory = ThreadFactoryBuilder.create().setNamePrefix("myThread-").build();
六、拒絕策略
當(dāng)線程池內(nèi)工作線程數(shù)大于maximumPoolSize時(shí),線程就不再接受任務(wù),執(zhí)行對(duì)應(yīng)的拒絕策略;目前支持的拒絕策略有四種:
1.AbortPolicy(默認(rèn)):丟棄任務(wù)并拋出RejectedExecutionException
異常
2.CallerRunsPolicy:由調(diào)用者處理
3.DiscardOldestPolicy:丟棄隊(duì)列中最前面的任務(wù),并重新入隊(duì)列
4.DiscardPolicy:丟棄任務(wù)但不拋出異常
七、線程池的執(zhí)行邏輯
// 創(chuàng)建線程工廠 ThreadFactory threadFactory = ThreadFactoryBuilder.create().setNamePrefix("myThread-").build(); // 創(chuàng)建線程池 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), threadFactory, new ThreadPoolExecutor.AbortPolicy());
八、execute()方法
// 組合值;保存了線程池的工作狀態(tài)和工作線程數(shù) private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
public void execute(Runnable command) { // 任務(wù)為空 拋出NPE if (command == null) throw new NullPointerException(); // 獲取線程池狀態(tài) int c = ctl.get(); // 如果工作線程數(shù)小于核心線程數(shù)就創(chuàng)建新線程 if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } // 如果線程池處于Running狀態(tài),就把任務(wù)放在隊(duì)列尾部 if (isRunning(c) && workQueue.offer(command)) { // 重新檢查線程池狀態(tài) int recheck = ctl.get(); // 如果線程池不是Running狀態(tài),就移除剛才添加的任務(wù),并執(zhí)行拒絕策略 if (! isRunning(recheck) && remove(command)) reject(command); // 是Running狀態(tài),就添加線程 else if (workerCountOf(recheck) == 0) addWorker(null, false); } // 添加任務(wù)失敗,執(zhí)行拒絕策略 else if (!addWorker(command, false)) reject(command); } // addWorker()完成線程的創(chuàng)建
九、執(zhí)行流程
到此這篇關(guān)于詳解Java線程池的使用及工作原理的文章就介紹到這了,更多相關(guān)Java線程池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)企業(yè)員工管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)企業(yè)員工管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02Spring中@Configuration和@Component注解的區(qū)別及原理
這篇文章主要介紹了Spring中@Configuration和@Component注解的區(qū)別及原理,從功能上來(lái)講,這些注解所負(fù)責(zé)的功能的確不相同,但是從本質(zhì)上來(lái)講,Spring內(nèi)部都將其作為配置注解進(jìn)行處理,需要的朋友可以參考下2023-11-11Springmvc如何實(shí)現(xiàn)向前臺(tái)傳遞數(shù)據(jù)
這篇文章主要介紹了Springmvc如何實(shí)現(xiàn)向前臺(tái)傳遞數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07Mybatis使用update更新值為null時(shí)不生效問(wèn)題解決
這篇文章主要介紹了Mybatis使用update更新值為null時(shí)不生效問(wèn)題解決,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06java開(kāi)發(fā)https請(qǐng)求ssl不受信任問(wèn)題解決方法
這篇文章主要介紹了java開(kāi)發(fā)https請(qǐng)求ssl不受信任問(wèn)題解決方法,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01Spring 重定向(Redirect)指南及相關(guān)策略問(wèn)題
本文介紹了在Spring中實(shí)現(xiàn)重定向的三種不同方法,在執(zhí)行這些重定向時(shí)如何處理/傳遞屬性以及如何處理HTTP POST請(qǐng)求的重定向。關(guān)于Spring 重定向(Redirect)指南的相關(guān)知識(shí)大家參考下本文2017-11-11Java matches類,Pattern類及matcher類用法示例
這篇文章主要介紹了Java matches類,Pattern類及matcher類用法,結(jié)合實(shí)例形式分析了java matches類,Pattern類及matcher類針對(duì)字符串常見(jiàn)操作技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2019-03-03Spring?Boot常用的參數(shù)驗(yàn)證技巧和使用方法
Spring Boot是一個(gè)使用Java編寫(xiě)的開(kāi)源框架,用于快速構(gòu)建基于Spring的應(yīng)用程序,這篇文章主要介紹了Spring?Boot常用的參數(shù)驗(yàn)證技巧和使用方法,需要的朋友可以參考下2023-09-09