併發程式設計 Executors(二 自定義執行緒池)

2021-08-30 11:38:22 字數 1933 閱讀 6364

前面介紹到,executor的執行緒池工廠通過threadpoolexecutor來構建帶有特定功能的執行緒池,同樣,也可以使用threadpoolexecutor來構建自定義執行緒池。

通過threadpoolexecutor構建自定義執行緒池比較關鍵的是其建構函式中所傳入的佇列型別。

使用有界佇列時:若有新的任務需要執行時,如果執行緒池實際執行緒數小於corepoolsize,則優先建立執行緒,若大於corepoolsize,則會將任務加入佇列,若佇列已滿,則在匯流排程數不大於maximumpoolsize的前提下建立新的執行緒,若執行緒數大於maximumpoolsize,則執行拒絕策略或其他自定義處理策略。下面舉一段小例子:

類:有界佇列的執行緒池

public static void main(string args)
執行效果如圖:

mytask [taskid=1, taskname=張三提交的任務:吃飯]

mytask [taskid=5, taskname=錢七提交的任務:今天我帶的是速效救心丸!]

mytask [taskid=2, taskname=李四提交的任務:睡覺]

mytask [taskid=3, taskname=王五提交的任務:寫bug]

mytask [taskid=4, taskname=趙六提交的任務:錢七,你今天帶藥了嗎?]

顯然,任務12345的執行順序為:1先到且立即執行,2、3、4任務到達後存放進arrayblockingqueue佇列,任務5到達後執行緒池開啟最大執行緒數(2),且立即執行了任務5,之後再依次執行了arrayblockingqueue佇列裡邊的任務2、3、4。

將任務六放行,執行結果如圖:

mytask [taskid=1, taskname=張三提交的任務:吃飯]

嘀 ___好人卡

mytask [taskid=5, taskname=錢七提交的任務:今天我帶的是速效救心丸!]

mytask [taskid=2, taskname=李四提交的任務:睡覺]

mytask [taskid=3, taskname=王五提交的任務:寫bug]

mytask [taskid=4, taskname=趙六提交的任務:錢七,你今天帶藥了嗎?]

顯然,在任務5到達後(此時任務1正在執行中,任務2、3、4已經放入佇列),任務5被立即執行,此時任務6到達,但此時執行緒池執行緒個數已經達到最大且任務佇列也已經滿了,所以執行了jdk提供的預設的拒絕策略,任務6不被執行,而在任務佇列中的任務2、3、4則繼續依次執行。

使用無界佇列(linkedblockingqueue)時:與有界佇列相比,除非系統資源耗盡,否則不會出現任務入隊失敗的情況。當有新任務到來時,系統的執行緒數小於corepoolsize時,則新建執行緒以執行任務,當執行緒數達到核心執行緒數個數之後就不會再增加執行緒,如果此時有新的任務到達,則將任務放到任務佇列裡邊。當任務建立和處理的速度差異很大時,任務佇列就會持續增加,知道系統記憶體被耗盡。下面舉一段小例子:

public class 無界佇列的執行緒池 implements runnable  catch (interruptedexception e) 

} public static void main(string args) throws exception

int size = queue.size();

while(size > 0 )

}}

jdk提供的拒絕策略有:abortpolicy(直接丟擲乙個異常,阻止系統正常工作)、callerrunspolicy(只要執行緒池未關閉,直接在呼叫者執行緒中執行當前被丟棄的任務)、discardoldestpolicy(丟棄最老的乙個請求,嘗試再次提交當前任務)、discardpolicy(丟棄無法處理的任務,不給予任何處理)。

自定義拒絕策略可以通過實現rejectedexecutionhandler介面來構建。

執行緒併發庫之Executors

executors newfixedthreadpool 固定大小執行緒池 建立乙個可重用固定執行緒集合的執行緒池,以共享的無界佇列方式來執行這些執行緒 只有要請求的過 來,就會在乙個佇列裡等待執行 如果在關閉前的執行期間由於失敗而導致任何執行緒終止,那麼乙個新執行緒將代替它執行後續的任務 如果 需...

併發程式設計(二)

使得乙個物件在當前範圍之外可見。比如通過公開方法返回乙個物件的引用 通過類靜態變數公布物件.與之對應的是逸出,指不正確的發布物件,比如將乙個私有的物件發布出去,或者還沒有正確構造完成物件,此物件就已經對外部可見 共有四種方式安全地發布物件 在單例模式中,如何保證只例項化乙個物件並保證執行緒安全?下面...

JAVA併發程式設計(二)

一.可見性 讀操作能實時的看到寫操作最新寫入的值。在單執行緒中,讀操作總能得到寫操作寫入的值 但在多執行緒中,如果讀操作跟寫操作在不同的執行緒中執行,那麼讀操作將不一定能適時的看到其他執行緒寫入的值。二.重排序 在沒有使用同步的情況下,編譯器 處理器 執行時都有可能做操作的執行順序進行一些調整。三....