Java線程池是運用最多的併發框架,學號多線程以及合理的使用多線程可以帶來很大的好處,今天就來一起學習線程池相關的知識吧!
一、線程池的實現原理
當向線程池提交一個任務後,線程池會怎麼做呢?
- 首先線程池會在核心線程
corePoolSize
中找是否都在執行任務,如果不是,就創建一個新的線程來分執行這個任務 - 如果核心線程都在執行任務,此時線程池判斷工作隊列
BlockingQueue
是否已滿,如果沒滿,就把這個任務加到工作隊列中 - 如果工作隊列也滿了,線程池就判斷所有線程池中的線程
maximumPoolQueue
是否都在工作,如果不是,就創建一個新的工作線程來執行任務 - 如果都滿了,那就會交給飽和策略去處理這個任務
可以結合流程圖更好理解:
接下來展示一張在線程池中的執行流程圖:
(圖源自《Java併發編程的藝術》)
線程池在線程中執行任務分爲兩種情況:
- 在
execute()
方法中創建一個線程,讓這個線程執行任務 - 這個線程執行完任務後,回反覆的從
BlockingQueue
獲取任務來執行
二、使用線程池
1. 使用線程池的好處
在開發中,合理的使用線程池可以帶來很大的好處:
- 降低資源消耗,通過重複的利用以及創建的響線程降低線程創建和銷燬的消耗
- 提高響應速度,當任務到達時,任務不需要等待線程創建就可以執行
- 提高線程的可管理性,如果無線的創建線程,不僅會消耗系統的資源,還會降低系統的穩定性,使用線程池可以進行統一的分配和監控。
2.線程池的創建
我們可以通過ThreadPoolExecutor來創建一個線程池
這是它擁有的構造方法們,我們來看看這些參數分別是什麼:
- corePoolSize —— 線程池的基本大小:當提交一個任務到線程池是,線程池會創建一個線程來執行任務,即使其它空閒的基本線程能夠執行新任務也會創建線程,等到任務數大於線程池基本大小時就不再創建。
- maximumPoolSize —— 線程池中允許的最大線程數 ,如果任務隊列滿了並且已經創建的線程小於最大線程數,則線程池會再創建新的線程執行任務。
- keepAliveTime —— 當線程數大於核心時,這是多餘的空閒線程在終止之前等待新任務的最大時間。 超過這個時間線程就會被終止
- unit —— keepAliveTime參數的時間單位 ,可選單位有:天、小時、分鐘、毫秒、微秒、納秒
- workQueue —— 在執行任務之前用於保存任務的隊列。 這個隊列只會保存execute方法提交的Runnable任務。
可以選擇以下幾個阻塞隊列:
(1) ArrayBlockingQueue: 一個基於數組結構的有界阻塞隊列,按先進先出對元素排序
(2) LinkedBlockingQueue:一個基於鏈表結構的阻塞隊列,按先進先出排序元素,吞吐量高於ArrayBlockingQueue
(3)PriorityBlockingQueue:一個具有優先級的無限阻塞隊列 - handler —— 執行被阻止時使用的處理程序,因爲達到線程限制和隊列容量
有以下四種飽和策略(拒絕策略):
(1)AbortPolicy:直接拋出異常
(2)CallerRunsPolicy:只用調用者所在的這個線程來運行任務
(3)DiscardPolicy:不處理,丟棄掉,。如果線程隊列已滿,則後續提交的任務都會被丟棄,且是靜默丟棄。
(4)DiscardOldestPolicy:丟棄掉隊列中最老的一個任務,執行當前任務
默認拒絕策略爲AbortPolicy
3. 向線程池提交任務
有兩種方式向線程池提交任務分別是execute()
和submit()
方法
execute()
方法用於提交不用返回值的任務,所以無法判斷任務是否被線程池執行成功。它的參數是一個Runnable
的實例。
submit()
方法用於提交需要返回值的任務。線程會返回一個future類型的對象,通過這個對象可以判斷任務是否執行成功。
4. 關閉線程池
可以通過調用線程池的shutdown()
或者shutdownNow()
來關閉線程池,它的原理是遍歷線程池中所有的線程,然後逐個調用線程的interrupt()方法中斷線程,所以無法響應中斷的任務有可能永遠無法終止。
二者的區別是:
shutdownNow()
首先iang線程池的狀態設爲STOP
,然後嘗試停止所有正在執行或暫停的線程,並返回等待執行任務的列表。
shutdown()
知識將線程池的狀態設置爲SHUTDOWN
,然後中斷所有沒有正在執行的任務。
通常調用shutdown()
方法關閉線程池,如果線程池中的任務不一定要執行完,可以調用shutdownNow()
方法。
嘮嘮叨叨:
這就是線程池的一些基本知識,更多的還是要在實踐中慢慢體會,本文參考《Java併發編程的藝術》一書,有任何問題歡迎評論指正,也歡迎點贊關注一起進步。