深入學習執行緒池總結(二)

2021-09-22 12:34:08 字數 2821 閱讀 5307

1、常用的執行緒方法

public threadpoolexecutor(int corepoolsize,int maximumpoolsize,long keepalivetime,timeunit 

unit,blockingqueueworkqueue,threadfactory threadfactory,

rejectedexecutionhandler handler)

2、解析各個引數的含義

corepoolsize

執行緒池中的核心執行緒數,當提交乙個任務時,執行緒池建立乙個新執行緒執行任務,直到當前執行緒數等於corepoolsize;如果當前執行緒數為corepoolsize,繼續提交的任務被儲存到阻塞佇列中,等待被執行;

如果執行了執行緒池的prestartallcorethreads()方法,執行緒池會提前建立並啟動所有核心執行緒。

maximumpoolsize

執行緒池中允許的最大執行緒數。如果當前阻塞佇列滿了,且繼續提交任務,則建立新的執行緒執行任務,前提是當前執行緒數小於maximumpoolsize

keepalivetime

workqueue必須是blockingqueue阻塞佇列。當執行緒池中的執行緒數超過它的corepoolsize的時候,執行緒會進入阻塞佇列進行阻塞等待。通過workqueue,執行緒池實現了阻塞功能;

用於儲存等待執行的任務的阻塞佇列,一般來說,我們應該盡量使用有界佇列,因為使用無界佇列作為工作佇列會對執行緒池帶來如下影響。

1)當執行緒池中的執行緒數達到corepoolsize後,新任務將在無界佇列中等待,因此執行緒池中的執行緒數不會超過corepoolsize。

2)由於1,使用無界佇列時maximumpoolsize將是乙個無效引數。

3)由於1和2,使用無界佇列時keepalivetime將是乙個無效引數。

4)更重要的,使用無界queue可能會耗盡系統資源,有界佇列則有助於防止資源耗盡,同時即使使用有界佇列,也要盡量控制佇列的大小在乙個合適的範圍。

所以一般會使用,arrayblockingqueue、linkedblockingqueue、synchronousqueue、priorityblockingqueue。

threadfactory

建立執行緒的工廠,通過自定義的執行緒工廠可以給每個新建的執行緒設定乙個具有識別度的執行緒名,當然還可以更加自由的對執行緒做更多的設定,比如設定所有的執行緒為守護執行緒。

參見**cn.enjoyedu.ch6. threadpooladv

executors靜態工廠裡預設的threadfactory,執行緒的命名規則是「pool-數字-thread-數字」。

rejectedexecutionhandler

執行緒池的飽和策略,當阻塞佇列滿了,且沒有空閒的工作執行緒,如果繼續提交任務,必須採取一種策略處理該任務,執行緒池提供了4種策略:

(1)abortpolicy:直接丟擲異常,預設策略;

(2)callerrunspolicy:用呼叫者所在的執行緒來執行任務;

(3)discardoldestpolicy:丟棄阻塞佇列中靠最前的任務,並執行當前任務;

(4)discardpolicy:直接丟棄任務;

當然也可以根據應用場景實現rejectedexecutionhandler介面,自定義飽和策略,如記錄日誌或持久化儲存不能處理的任務。

1)如果當前執行的執行緒少於corepoolsize,則建立新執行緒來執行任務(注意,執行這一步驟需要獲取全域性鎖)。

2)如果執行的執行緒等於或多於corepoolsize,則將任務加入blockingqueue。

3)如果無法將任務加入blockingqueue(佇列已滿),則建立新的執行緒來處理任務。

4)如果建立新執行緒將使當前執行的執行緒超出maximumpoolsize,任務將被拒絕,並呼叫rejectedexecutionhandler.rejectedexecution()方法。

1、提交任務:

1)execute()方法用於提交不需要返回值的任務,所以無法判斷任務是否被執行緒池執行成功。

2)submit()方法用於提交需要返回值的任務。執行緒池會返回乙個future型別的物件,通過這個future物件可以判斷任務是否執行成功,並且可以通過future的get()方法來獲取返回值,get()方法會阻塞當前執行緒直到任務完成,而使用get(long timeout,timeunit unit)方法則會阻塞當前執行緒一段時間後立即返回,這時候有可能任務沒有執行完。

2、關閉任務:

可以通過呼叫執行緒池的shutdown或shutdownnow方法來關閉執行緒池。它們的原理是遍歷執行緒池中的工作執行緒,然後逐個呼叫執行緒的interrupt方法來中斷執行緒,所以無法響應中斷的任務可能永遠無法終止。但是它們存在一定的區別,shutdownnow首先將執行緒池的狀態設定成stop,然後嘗試停止所有的正在執行或暫停任務的執行緒,並返回等待執行任務的列表,而shutdown只是將執行緒池的狀態設定成shutdown狀態,然後中斷所有沒有正在執行任務的執行緒。

只要呼叫了這兩個關閉方法中的任意乙個,isshutdown方法就會返回true。當所有的任務都已關閉後,才表示執行緒池關閉成功,這時呼叫isterminaed方法會返回true。至於應該呼叫哪一種方法來關閉執行緒池,應該由提交到執行緒池的任務特性決定,通常呼叫shutdown方法來關閉執行緒池,如果任務不一定要執行完,則可以呼叫shutdownnow方法。

Python深入學習筆記(二)

計數器counter counter類是自python2.7起增加的,屬於字典類的子類,是乙個容器物件,主要用來統計雜湊物件,支援集合操作 其中後兩項分別返回兩個counter物件各元素的最小值和最大值。from collections import counter c counter succes...

深入學習redis 的執行緒模型

redis 內部使用檔案事件處理器 file event handler,它是單執行緒的,所以redis才叫做單執行緒模型。它採用io多路復用機制同時監聽多個 socket,將產生事件的 socket 壓入記憶體佇列中,事件分派器根據 socket 上的事件型別來選擇對應的事件處理器進行處理。檔案事...

執行緒池學習總結

核心執行緒數 5 工作佇列 100 最大執行緒數 10 拒絕策略 講解1 執行緒全為空 1.執行緒首先占用核心執行緒中的空餘執行緒 2.當核心執行緒數5個全部被占用,此時又來乙個執行緒需要處理,則此執行緒被放入工作佇列中 3.當工作佇列中的100個空餘執行緒位置均被占用時,此時又來乙個執行緒需要處理...