1. 程式人生 > 其它 >執行緒池 七個引數

執行緒池 七個引數

執行緒池

為了非同步減少阻塞

java多執行緒開發時,常常用到執行緒池技術,這篇文章是對建立java執行緒池時的七個引數的詳細解釋。從原始碼中可以看出,執行緒池的建構函式有7個引數,分別是corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler。下面會對這7個引數一一解釋。

引數一:corePoolSize 執行緒池核心執行緒大小

執行緒池中會維護一個最小的執行緒數量,即使這些執行緒處理空閒狀態,他們也不會 被銷燬,除非設定了allowCoreThreadTimeOut。這裡的最小執行緒數量即是corePoolSize。

引數二:maximumPoolSize 執行緒池最大執行緒數量

一個任務被提交到執行緒池以後,首先會找有沒有空閒存活執行緒,如果有則直接執行,如果沒有則會快取到工作佇列(後面會介紹)中,如果工作佇列滿了,才會建立一個新執行緒,然後從工作佇列的頭部取出一個任務交由新執行緒來處理,而將剛提交的任務放入工作佇列尾部。執行緒池不會無限制的去建立新執行緒,它會有一個最大執行緒數量的限制,這個數量即由maximunPoolSize指定。

引數三:keepAliveTime 空閒執行緒存活時間

一個執行緒如果處於空閒狀態,並且當前的執行緒數量大於corePoolSize,那麼在指定時間後,這個空閒執行緒會被銷燬,這裡的指定時間由keepAliveTime

來設定。

引數四:unit 空間執行緒存活時間單位

keepAliveTime的計量單位

引數五:workQueue 工作佇列

新任務被提交後,會先進入到此工作佇列中,任務排程時再從佇列中取出任務。jdk中提供了四種工作佇列:

ArrayBlockingQueue

基於陣列的有界阻塞佇列,按FIFO排序。新任務進來後,會放到該佇列的隊尾,有界的陣列可以防止資源耗盡問題。當執行緒池中執行緒數量達到corePoolSize後,再有新任務進來,則會將任務放入該佇列的隊尾,等待被排程。如果佇列已經是滿的,則建立一個新執行緒,如果執行緒數量已經達到maxPoolSize,則會執行拒絕策略。

LinkedBlockingQuene

基於連結串列的無界阻塞佇列(其實最大容量為Interger.MAX),按照FIFO排序。由於該佇列的近似無界性,當執行緒池中執行緒數量達到corePoolSize後,再有新任務進來,會一直存入該佇列,而不會去建立新執行緒直到maxPoolSize,因此使用該工作佇列時,引數maxPoolSize其實是不起作用的。

SynchronousQuene

一個不快取任務的阻塞佇列,生產者放入一個任務必須等到消費者取出這個任務。也就是說新任務進來時,不會快取,而是直接被排程執行該任務,如果沒有可用執行緒,則建立新執行緒,如果執行緒數量達到maxPoolSize,則執行拒絕策略。

PriorityBlockingQueue

具有優先順序的無界阻塞佇列,優先順序通過引數Comparator實現。

還有幾種其他的阻塞佇列

引數六:threadFactory 執行緒工廠

建立一個新執行緒時使用的工廠,可以用來設定執行緒名、是否為daemon執行緒等等

引數七:handler 拒絕策略

當工作佇列中的任務已到達最大限制,並且執行緒池中的執行緒數量也達到最大限制,這時如果有新任務提交進來,該如何處理呢。這裡的拒絕策略,就是解決這個問題的,jdk中提供了4中拒絕策略:

CallerRunsPolicy

該策略下,在呼叫者執行緒中直接執行該被拒絕任務的run方法,除非執行緒池已經shutdown,則直接拋棄任務。

AbortPolicy

該策略下,直接丟棄任務,並丟擲RejectedExecutionException異常。

DiscardPolicy

該策略下,直接丟棄任務,什麼都不做。

DiscardOldestPolicy

該策略下,拋棄進入佇列最早的那個任務,然後嘗試把這次拒絕的任務放入佇列

到此,構造執行緒池時的七個引數,就全部介紹完畢了。

排隊多出來的可以丟到kafaka上