java、多線程、線程池
面試非常喜歡問線程池,平時可能大家會使用但原理可能不知道。
面試悲劇回顧
- 面試官:線程池講講吧
- 程序汪汪:不會啊,我就會用下。
- 面試官:那你回去等電話通知吧
【面試失敗,線程池原理一無所知,回去好好複習總結下,然後繼續戰鬥】
線程池【優點】
- 降低資源消耗,減少創建和銷燬線程對系統資源的消耗,線程複用
- 提高響應速度,任務到達時,不用重新創建線程,可以使用已經創建好的線程執行。
- 提高線程的管理性:線程統一管理維護,方便優化監控。
線程池的實現原理
- 【簡單解釋版】預先創建好線程然後保存起來,在需要的時候直接複用線程就可以。
- 【複雜解釋版】
- 1:客服端提交任務到線程池中
- 2:線程池處理
- 3:先判斷 核心線程池corePoolSize 中線程池是否都在執行任務。如果不是,就創建一個線程來執行任務。如果都在執行任務,就進入下個流程。
- 4:判斷工作隊列 workQueue 是否已滿。如果沒滿,就將任務存入工作隊列中,如果隊列滿了,就進入下個流程。
- 5:判斷 maximumPoolSize線程池中線程是否都在工作狀態。如果不是,就創建新線程並執行任務,如果是就執行拒絕策略。
具體執行流程見下圖
ThreadPoolExecutor構造參數
- ThreadPoolExecutor是線程池的具體實現
- 核心參數說明
- corePoolSize:核心線程數,指線程池中報錯的線程數,包含空閒線程
- maximumPoolSize :線程池中允許的最大線程數
- keepAliveTime:當線程大於核心線程時,多餘空閒線程等待新任務的最長時間
- unit:參數中的時間單位
- workQueue:當線程池中的線程數超過他的corePoolSize的時候,線程會進入阻塞隊列進行阻塞等待。
- threadFactory:創建線程的工廠
- RejectedExecutionHanadler:線程池的拒絕策略,當阻塞隊列滿了並且沒有空閒工作線程,如果繼續提交任務,就採取拒絕策略。 【默認策略是直接拋出異常的】
Spring的線程配置
線程池參數配置考慮因素
- 任務類型:CPU密集類型任務,還是IO密集類型任務
- 任務的優先級
- 任務執行的時間長短
- 任務依賴情況:數據庫連接資源、下游系統資源 【千萬要避免把數據庫資源吃光,下游系統併發壓宕機了】
- 牛逼的公司會定製線程池框架,加入一些個性化的功能,做到動態配置、監控日誌等等。
注意
- 線程池不允許使用Executors去創建,而是通過ThreadPoolExceutor的方式,這樣能明確線程池的運行規則,規避資源耗盡的風險。
我這裡有具體多線程的例子和相關知識點文字,傳送門
我的其他技術文章,歡迎一起學習交流
閱讀更多 程序汪汪 的文章