更新時間:2020-11-16 17:36:42 來源:動力節點 瀏覽3784次
線程是一種寶貴的資源,也是一種有限的資源,創建和銷毀線程需要付出不菲的代價。這時候就要用到線程池了,線程池維護著多個線程,等待著監督管理者分配可并發執行的任務。這避免了在處理短時間任務時創建與銷毀線程的代價。本文我們就一起來深入學習線程池工作流程。
線程池工作流程可以拆分成以下幾個部分:
當向線程池提交一個新的任務時,線程池有三種處理情況,分別是:創建一個工作線程來執行該任務、將任務加入阻塞隊列、拒絕該任務。提交任務的過程也可以拆分成以下幾個部分:當工作線程數小于核心線程數時,直接創建新的核心工作線程當工作線程數不小于核心線程數時,就需要嘗試將任務添加到阻塞隊列中去如果能夠加入成功,說明隊列還沒有滿,那么需要做以下的二次驗證來保證添加進去的任務能夠成功被執行驗證當前線程池的運行狀態,如果是非RUNNING狀態,則需要將任務從阻塞隊列中移除,然后拒絕該任務驗證當前線程池中的工作線程的個數,如果為0,則需要主動添加一個空工作線程來執行剛剛添加到阻塞隊列中的任務如果加入失敗,則說明隊列已經滿了,那么這時就需要創建新的“臨時”工作線程來執行任務如果創建成功,則直接執行該任務如果創建失敗,則說明工作線程數已經等于最大線程數了,則只能拒絕該任務了。
創建工作線程需要做一系列的判斷,需要確保當前線程池可以創建新的線程之后,才能創建。首先,當線程池的狀態是 SHUTDOWN 或者 STOP 時,則不能創建新的線程。另外,當線程工廠創建線程失敗時,也不能創建新的線程。還有就是當前工作線程的數量與核心線程數、最大線程數進行比較,如果前者大于后者的話,也不允許創建。除此之外,會嘗試通過 CAS 來自增工作線程的個數,如果自增成功了,則會創建新的工作線程,即 Worker 對象。然后加鎖進行二次驗證是否能夠創建工作線程,最后如果創建成功,則會啟動該工作線程。
當工作線程創建成功后,也就是 Worker 對象已經創建好了,這時就需要啟動該工作線程,讓線程開始干活了,Worker 對象中關聯著一個 Thread,所以要啟動工作線程的話,只要通過 worker.thread.start() 來啟動該線程即可。啟動完了之后,就會執行 Worker 對象的 run 方法,因為 Worker 實現了 Runnable 接口,所以本質上 Worker 也是一個線程。通過線程 start 開啟之后就會調用到 Runnable 的 run 方法,在 worker 對象的 run 方法中,調用了 runWorker(this) 方法,也就是把當前對象傳遞給了 runWorker 方法,讓他來執行。
在 runWorker 方法被調用之后,就是執行具體的任務了,首先需要拿到一個可以執行的任務,而 Worker 對象中默認綁定了一個任務,如果該任務不為空的話,那么就是直接執行。執行完了之后,就會去阻塞隊列中獲取任務來執行,而獲取任務的過程,需要考慮當前工作線程的個數。如果工作線程數大于核心線程數,那么就需要通過 poll 來獲取,因為這時需要對閑置的線程進行回收;如果工作線程數小于等于核心線程數,那么就可以通過 take 來獲取了,因此這時所有的線程都是核心線程,不需要進行回收,前提是沒有設置 allowCoreThreadTimeOut。
以上就是整個線程池工作流程,我們對每個線程池工作步驟都進行了詳細的講解,為了加深對線程池的理解可以觀看本的多線程教程,深入學習更多的還沒有掌握的線程池知識。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習