您好,登錄后才能下訂單哦!
如何通過ThreadPoolExecutor的方式創(chuàng)建線程池,針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
線程池不建議使用Executors去創(chuàng)建,而是通過ThreadPoolExecutor的方式,這樣的處理方式讓寫的同學(xué)更加明確線程池的運行規(guī)則,規(guī)避資源耗盡的風(fēng)險。
Executors各個方法的弊端:
newFixedThreadPool 和 newSingleThreadExecutor:
主要問題是堆積的請求處理隊列可能會耗費非常大的內(nèi)存,甚至OOM。(筆者注:阻塞隊列均采用LinkedBlockingQueue)
newCachedThreadPool 和 newScheduledThreadPool:
主要問題是線程數(shù)最大數(shù)是Integer.MAX_VALUE,可能會創(chuàng)建數(shù)量非常多的線程,甚至OOM。
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 // 拒絕策略 )
線程池運行原理:
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(先進后出)
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)知識。
免責(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)容。