執行緒池是怎樣執行任務的?
我曾經在乙個面試中被問到,說說執行緒池是怎樣執行任務的,由於對這個知識點不是很清楚,我當時很緊張,回答的不好,因此面試完當天我就惡補了這個知識點,現在來重溫一下說到執行任務,我們就必須先談談提交任務。
提交任務的方式有兩種,一種是execute,還有一種是submit。
這兩種方式在前面的章節已經講過,它們的區別在於execute只能提交runnable任務,也就是無返回之任務。而submit既可以提交runnable部任務,也可以提交callable任務,也就是有返回值的任務。雖然兩者提交任務的種類有差異,但是他們最終處理任務的方法是相同的,都是threadpoolexecutor類的execute方法。
execute方法的實現就在 threadpoolexecutor內中submit方法的實現,是在attributeexecuteservice抽象類,
看看submit方法內部做了哪些操作,首先判斷任務是否為空,當任務為空時,拋乙個空指標異常,當任務不為空,將任務轉為有返回值任務。然後呼叫 execute方法執行,該任務此處呼叫的是threadpoolexecutor類中的execute方法,最後返回future物件拿到結果,呼叫者再通過future物件拿到執行結果。
接下來重點講講execute方法。execute方法可分為三個部分來看,第一部分判斷核心執行緒數是否已滿,能否再加入新的核心執行緒。第二部分判斷任務佇列是否已滿,能否再加入新的任務。第三部分判斷執行緒池中的執行緒是否已滿,能否再加入新的執行緒。
接下來以此來看這三個部分。
判斷核心限值數是否已滿,也就是這行**workaccountof方法的作用是獲取當年執行緒池中有多少執行緒,corepoolsize的屬性記錄了當前限制池中和多少核心執行緒,當池中的限制數小於核心限值數,也就是核心執行緒沒滿時,
當然單獨設定允許銷毀核心執行緒除外,addworker方法\我們就簡單的說完了。
執行緒新增成功會怎樣?執行緒新增成功,執行完任務這個流程就結束了,直接return這是新增成功的情況。
假設新增失敗,也就是核心執行緒以滿,繼續往下執行。
ctl記錄著執行緒池狀態和池中有多少執行緒,這裡獲取它的值是為後續流程做準備。
當核心執行緒已滿時,我們就要考慮將任務先放入任務佇列中,此時要判斷一下任務佇列是否已滿,isrunning判斷執行緒池是否還在執行,如果沒在執行,好,直接跳過這個流程,進入下乙個流程。如果執行緒池還在執行,
將任務新增至任務佇列中,
也就是呼叫workerqueue的offer方法,如果新增成功,任務將在佇列中等待被執行,看見流程圖是怎樣的,任務佇列沒滿,任務新增成功,等待被執行,這就是佇列沒滿的情況。
來看左邊的**部分,if語句裡面還有任務新增後的操作,再次獲取執行緒池狀態,
檢查執行緒池是否還在執行,如果沒執行就從佇列中移除任務,然後拒絕任務,
如果執行緒池還在執行,那麼就檢查池中的執行緒數量是否為0,也就是池中已經沒有可用的執行緒,那麼就新增乙個非核心執行緒。
第二部分看完再來看
當任務佇列已滿時,我們就需要考慮往執行緒池中新增執行緒的,
如果池中的執行緒沒滿,那麼就直接新增執行緒並執行提交的任務,這是一種結果。
還有一種結果是當池中的執行緒已滿,無法再往裡面新增新執行緒時,我們只有將任務拒絕掉,
這是第三部分看完。我們已經畫完整個流程圖,也已看完**執行過程,應該來說**搭配著流程圖一起看,這個過程理解起來更容易。
最後總結一下本節內容,本節介紹了執行緒池執行任務的流程,如圖所示,以後在面試中遇到類似的問題就可以輕鬆應對了,甚至只看execute的方法,源**能否在紙上將其流程圖畫出來,看自己掌握了多少流程圖。
附錄:筆記完整文字:
基於C 11的執行緒池,指定執行緒執行任務
基於c 11的執行緒池,如果執行緒與任務無關,比較好實現,但是!opengl這種任務需要繪製上下文,就是需要指定執行緒執行任務。thread pool.hpp ifndef thread pool h define thread pool h include include include incl...
執行緒池 任務延時執行
我在做乙個匯入功能,匯入的邏輯都是呼叫的頁面介面。介面執行邏輯 將資料儲存到資料庫,然後再呼叫job任務加工歷史資料。使用者在頁面上操作是ok的,畢竟每操作一下,介面最多呼叫一次。但是匯入就不一樣了,相當於使用者一直在對著頁面點點點 這會導致後面歷史任務的加工出現問題。在匯入的時候,我需要先讓基本資...
執行緒池多工的執行順序
執行緒池場景 面試官 假設我們有乙個執行緒池,核心執行緒數為10,最大執行緒數也為20,任務隊列為100。現在來了100個任務,執行緒池裡現在有幾個執行緒執行?粉絲豪 應該是10吧。面試官 你確定?粉絲豪 確定啊,就是10 於是乎,粉絲豪就回去等通知了 其實這道題正確的答案是 不一定!因為並沒指明是...