溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何通過ThreadPoolExecutor的方式創(chuàng)建線程池

發(fā)布時間:2022-01-04 15:10:37 來源:億速云 閱讀:103 作者:柒染 欄目:大數(shù)據(jù)

如何通過ThreadPoolExecutor的方式創(chuàng)建線程池,針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

線程池不建議使用Executors去創(chuàng)建,而是通過ThreadPoolExecutor的方式,這樣的處理方式讓寫的同學(xué)更加明確線程池的運行規(guī)則,規(guī)避資源耗盡的風(fēng)險。

Executors各個方法的弊端:

  1. newFixedThreadPool 和 newSingleThreadExecutor:
    主要問題是堆積的請求處理隊列可能會耗費非常大的內(nèi)存,甚至OOM。(筆者注:阻塞隊列均采用LinkedBlockingQueue)

  2. newCachedThreadPool 和 newScheduledThreadPool:
    主要問題是線程數(shù)最大數(shù)是Integer.MAX_VALUE,可能會創(chuàng)建數(shù)量非常多的線程,甚至OOM。

ThreadPoolExecutor函數(shù)

Executors提供了四種創(chuàng)建線程池的方法,實際上Executors的底層也是調(diào)用了ThreadPoolExecutor。函數(shù)定義如下:

public ThreadPoolExecutor(int corePoolSize,  // 線程池的核心線程數(shù)                          
int maximumPoolSize, // 線程池的最大線程數(shù)                          
long keepAliveTime, // 當(dāng)線程數(shù)大于核心時,多余的空閑線程等待新任務(wù)的存活時間。                          
TimeUnit unit, // keepAliveTime的時間單位                          
ThreadFactory threadFactory, // 線程工廠                          
BlockingQueue<Runnable> workQueue,// 用來儲存等待執(zhí)行任務(wù)的隊列                          
RejectedExecutionHandler handler // 拒絕策略                          )

線程池運行原理:

如何通過ThreadPoolExecutor的方式創(chuàng)建線程池

函數(shù)參數(shù)補充說明

  1. workQueue有以下七種選擇:

  • ArrayBlockingQueue: 一個由數(shù)組結(jié)構(gòu)組成的有界阻塞隊列(數(shù)組結(jié)構(gòu)可配合指針實現(xiàn)一個環(huán)形隊列)。

  • LinkedBlockingQueue: 一個由鏈表結(jié)構(gòu)組成的有界阻塞隊列,而在未指明容量時,容量默認為Integer.MAX_VALUE。

  • PriorityBlockingQueue: 一個支持優(yōu)先級排序的無界阻塞隊列,對元素沒有要求,可以實現(xiàn)Comparable接口也可以提供Comparator來對隊列中的元素進行比較,跟時間沒有任何關(guān)系,僅僅是按照優(yōu)先級取任務(wù)。

  • DelayQueue: 同PriorityBlockingQueue,也是二叉堆實現(xiàn)的優(yōu)先級主阻塞隊列。要求元素都實現(xiàn)Delayed接口,通過執(zhí)行時延從隊列中提取任務(wù),時間沒到任務(wù)取不出來。

  • SynchronousQueue: 一個不存儲元素的阻塞隊列,消費者線程調(diào)用take()方法的時候就會發(fā)生阻塞,直到有一個生產(chǎn)者線程生產(chǎn)了一個元素,消費者線程就可以拿到這個元素并返回;生產(chǎn)者線程調(diào)用put()方法的時候就會發(fā)生阻塞,直到有一個消費者線程消費了一個元素,生產(chǎn)者才會返回。

  • LinkedTransferQueue: 它是ConcurrentLinkedQueue、LinkedBlockingQueue和SynchronousQueue的結(jié)合體,但是把它用在ThreadPoolExecutor中,和LinkedBlockingQueue行為一致。

  • LinkedBlockingDeque: 使用雙向隊列實現(xiàn)的雙端阻塞隊列,雙端意味著可以像普通隊列一樣FIFO(先進先出),可以以像棧一樣FILO(先進后出)

  1. handler有以下四種取值:

  • AbortPolicy(默認):丟棄任務(wù)并拋出RejectedExecutionException異常。

  • CallerRunsPolicy:由調(diào)用線程處理該任務(wù)。(例如io操作,線程消費速度沒有NIO讀取快,可能導(dǎo)致阻塞隊列一直增加,此時可以使用這個模式)

  • DiscardPolicy:丟棄任務(wù),但是不拋出異常。 (可以配合這種模式進行自定義的處理方式)

  • DiscardOldestPolicy:丟棄隊列最早的未處理任務(wù),然后重新嘗試執(zhí)行任務(wù)(重復(fù)執(zhí)行)

關(guān)于如何通過ThreadPoolExecutor的方式創(chuàng)建線程池問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI