常用執行緒池及適用場景

2021-09-28 19:26:34 字數 3545 閱讀 7152

arrayblockingqueue: (有界佇列) 是乙個陣列實現的有界阻塞佇列,按fifo排序量

linkedblockingqueue: 是乙個基於鍊錶實現的阻塞佇列,按fifo排序任務,可以設定容量,不設定使用integer.max_value (不設定就是無界佇列)newfixthreadpool,newsinglethreadexecutor使用此佇列

(吞吐量高於arrayblockingqueue)

delayqueue: (延遲佇列)是乙個任務定時週期的延遲執行的佇列。根據插入到佇列的先後。newscheduledtreadpool執行緒池使用這個佇列。

priorityblockingqueue: (優先順序佇列) 是具有優先順序的無界佇列;

synchronousqueue: (同步佇列) 乙個不儲存元素的阻塞佇列,每個插入操作必須等到另乙個執行緒的呼叫移除操作,否則插入操作一直處於阻塞狀態。吞吐量通常高於linkedblockingquene newcachedthreadpool 執行緒池使用此佇列。

newfixedthreadpool(固定數目的執行緒池)

newcachedthreadpool(可快取執行緒的執行緒池)

newsinglethreadexecutor(單執行緒的執行緒池)

newscheduledthreadpool(定時及週期執行的執行緒池)

public static executorservice newfixedthreadpool(int nthreads, threadfactory threadfactory)

使用場景:

fixedthreadpool核心執行緒池等於最大執行緒池,當前的執行緒數能夠比較穩定保證乙個數。能夠避免頻繁**執行緒和建立執行緒。故適用於處理cpu密集型的任務,確保cpu在長期被工作執行緒使用的情況下,盡可能少的分配執行緒,即適用長期的任務。

此方法的弊端是

到了執行緒池最大容量後,如果有任務完成讓出占用執行緒,那麼此執行緒就會一直處於等待狀態,而不會消亡,直到下乙個任務再次占用該執行緒。這就可能會使用無界佇列來存放排隊任務,當大量任務超過執行緒池最大容量需要處理時,佇列無線增大,使伺服器資源迅速耗盡。

public static executorservice newcachedthreadpool(

)

使用場景

newcacehedthreadpool 的最大特點就是,執行緒數量不固定。只要有空閒執行緒空閒時間超過keepalivetime,就會被**。有新的任務,檢視是否有執行緒處於空閒狀態,如果不是就直接建立新的任務。故適用用於併發不固定的短期小任務。

此方法的弊端是

執行緒池沒有最大執行緒數量限制,如果大量的任務同時提交,可能導致創執行緒過多會而導致資源耗盡。

public static executorservice newsinglethreadexecutor(

)

使用場景:

newsinglethreadexecutor 適用序列化任務,乙個任務接著乙個乙個任務的執行。

public scheduledthreadpoolexecutor(int corepoolsize)

使用:

scheduledthreadpoolexecutor  scheduled = new scheduledthreadpoolexecutor(2)

; scheduled.scheduleatfixedrate(new runnable(

)}, 0, 40, timeunit.milliseconds)

; //0表示首次執行任務的延遲時間,40表示每次執行任務的間隔時間

執行的時間間隔數值單位

使用場景:

scheduledthreadpoolexecutor 適用於定時操作一些任務

雖然executors為我們提供了構造執行緒池的便捷方法,對於伺服器程式我們應該杜絕使用這些便捷方法,而是直接使用執行緒池threadpoolexecutor的構造方法,避免無界佇列可能導致的oom以及執行緒個數限制不當導致的執行緒數耗盡等問題。executorcompletionservice提供了等待所有任務執行結束的有效方式,如果要設定等待的超時時間,則可以通過countdownlatch完成。

執行緒拒絕策略:

是系統超負荷執行的最後補救措施,,阻塞佇列滿了,最大執行緒池也滿了,jdk提供丟棄策略有如下四種:

(1)threadpoolexecutor.abortpolicy:丟擲rejectedexecutionexception異常,丟棄任務,阻止系統正常工作。 (executors類建立執行緒池的預設丟棄策略)

(2)threadpoolexecutor.discardpolicy:偷偷的丟棄任務,但是不丟擲異常。

(3)threadpoolexecutor.discardoldestpolicy:丟棄最老的任務(即隊首馬上要執行的任務),然後重新嘗試執行任務(重複此過程)

(4)threadpoolexecutor.callerrunspolicy:只要執行緒池未關閉,直接去呼叫執行緒池的執行緒中處理該任務,可能引起效能的急劇下降。

(1)execute沒有返回值;而submit有返回值,方便返回執行結果。

(2)submit方便進行exception處理,由於返回引數是future,如果執行期間丟擲了異常,可以使用future.get()進行捕獲。

合理的選擇執行緒池大小

cpu核數 * cpu核數 *(1+等待時間 / 計算時間)

執行緒池的幾種狀態:

running

會接受新任務,處理阻塞佇列的任務

呼叫 shutdown() 切換為shutdown 狀態

呼叫 shutdownnow() 切換到stop狀態

shutdown

不接受新任務,會處理阻塞佇列的任務

阻塞佇列的任務為空,執行緒池中的執行緒執行的任務也為空,變為tidying

stop

不接受新任務,不會處理阻塞佇列的任務,而且中斷正在執行的任務。

執行緒池中正在執行的任務為空,則變為tidying

tidying

表明所有任務執行完畢,記錄任務的數量為0

terminated() 執行完畢,進入terminated狀態

terminated

執行緒池徹底終止

執行緒池及適用場合

1 為什麼需要執行緒池?目前的大多數網路伺服器,包括web伺服器 email伺服器以及資料庫伺服器等都具有乙個共同點,就是單位時間內必須處理數目巨大的連線請求,但處理時間卻相對較短。傳統多執行緒方案中我們採用的伺服器模型則是一旦接受到請求之後,即建立乙個新的執行緒,由該執行緒執行任務。任務執行完畢後...

java執行緒池簡單介紹以及適用場景

newfixedthreadpool int nthads newsinglethreadexecutor newcachedthreadpool newscheduledthreadpool int corepoolsize 1 fixedthreadpool和 singlethreadpool ...

TiDB適用場景和不適用場景

一 tidb簡介 tidb 是 pingcap 公司受 google spanner f1 啟發而設計的開源分布式 htap hybrid transactional and analytical processing 資料庫,結合了傳統的 rdbms 和nosql 的最佳特性。tidb 相容 my...