您好,登錄后才能下訂單哦!
降低資源消耗。通過重復利用已創建的線程降低線程創建、銷毀線程造成的消耗。
提高響應速度。當任務到達時,任務可以不需要等到線程創建就能立即執行。
參數 | 說明 |
---|---|
corePoolSize | 核心線程數量,線程池維護線程的最少數量 |
maximumPoolSize | 線程池維護線程的最大數量 |
keepAliveTime | 線程池除核心線程外的其他線程的最長空閑時間,超過該時間的空閑線程會被銷毀 |
unit | keepAliveTime的單位,TimeUnit中的幾個靜態屬性:NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS |
workQueue | 線程池所使用的任務緩沖隊列 |
threadFactory | 線程工廠,用于創建線程,一般用默認的即可 |
handler | 線程池對拒絕任務的處理策略 |
當線程池任務處理不過來的時候(什么時候認為處理不過來后面描述),可以通過handler指定的策略進行處理,ThreadPoolExecutor提供了四種策略:
可以通過實現RejectedExecutionHandler接口自定義處理方式。
2.1. 如果此時線程池中的數量小于corePoolSize,即使線程池中的線程都處于空閑狀態,也要創建新的線程來處理被添加的任務。
2.2. 如果此時線程池中的數量等于corePoolSize,但是緩沖隊列workQueue未滿,那么任務被放入緩沖隊列。
2.3. 如果此時線程池中的數量大于等于corePoolSize,緩沖隊列workQueue滿,并且線程池中的數量小于maximumPoolSize,建新的線程來處理被添加的任務。
2.4. 如果此時線程池中的數量大于corePoolSize,緩沖隊列workQueue滿,并且線程池中的數量等于maximumPoolSize,那么通過 handler所指定的策略來處理此任務。
2.5. 當線程池中的線程數量大于 corePoolSize時,如果某線程空閑時間超過keepAliveTime,線程將被終止。這樣,線程池可以動態的調整池中的線程數。
總結即:處理任務判斷的優先級為 核心線程corePoolSize、任務隊列workQueue、最大線程maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務。
注意:
3.1. shutdown() 不接收新任務,會處理已添加任務
3.2. shutdownNow() 不接受新任務,不處理已添加任務,中斷正在處理的任務
4.1. ArrayBlockingQueue: 這是一個由數組實現的容量固定的有界阻塞隊列.
4.2. SynchronousQueue: 沒有容量,不能緩存數據;每個put必須等待一個take; offer()的時候如果沒有另一個線程在poll()或者take()的話返回false。
4.3. LinkedBlockingQueue: 這是一個由單鏈表實現的默認×××的阻塞隊列。LinkedBlockingQueue提供了一個可選有界的構造函數,而在未指明容量時,容量默認為Integer.MAX_VALUE。
隊列操作:
方法 | 說明 |
---|---|
add | 增加一個元索; 如果隊列已滿,則拋出一個異常 |
remove | 移除并返回隊列頭部的元素; 如果隊列為空,則拋出一個異常 |
offer | 添加一個元素并返回true; 如果隊列已滿,則返回false |
poll | 移除并返回隊列頭部的元素; 如果隊列為空,則返回null |
put | 添加一個元素; 如果隊列滿,則阻塞 |
take | 移除并返回隊列頭部的元素; 如果隊列為空,則阻塞 |
element | 返回隊列頭部的元素; 如果隊列為空,則拋出一個異常 |
peek | 返回隊列頭部的元素; 如果隊列為空,則返回null |
1. Executors.newCachedThreadPool();
說明: 創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程.
內部實現:new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.SECONDS,new SynchronousQueue<runnable>());</runnable>
2. Executors.newFixedThreadPool(int);
說明: 創建一個定長線程池,可控制線程最大并發數,超出的線程會在隊列中等待。
內部實現:new ThreadPoolExecutor(nThreads, nThreads,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<runnable>());</runnable>
3. Executors.newSingleThreadExecutor();
說明:創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照順序執行。
內部實現:new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<runnable>())</runnable>
4. Executors.newScheduledThreadPool(int);
說明:創建一個定長線程池,支持定時及周期性任務執行。
內部實現:new ScheduledThreadPoolExecutor(corePoolSize)
【附】阿里巴巴Java開發手冊中對線程池的使用規范
【強制】創建線程或線程池時請指定有意義的線程名稱,方便出錯時回溯。
正例:
public class TimerTaskThread extends Thread {
public TimerTaskThread(){
super.setName("TimerTaskThread");
...
}
}
【強制】線程資源必須通過線程池提供,不允許在應用中自行顯式創建線程。
說明: 使用線程池的好處是減少在創建和銷毀線程上所花的時間以及系統資源的開銷,解決資
源不足的問題。如果不使用線程池,有可能造成系統創建大量同類線程而導致消耗完內存或者
“過度切換”的問題。
說明: Executors 返回的線程池對象的弊端如下:
1) FixedThreadPool 和 SingleThreadPool:
允許的請求隊列長度為 Integer.MAX_VALUE,可能會堆積大量的請求,從而導致 OOM。
2) CachedThreadPool 和 ScheduledThreadPool:
允許的創建線程數量為 Integer.MAX_VALUE, 可能會創建大量的線程,從而導致 OOM。
ThreadPoolExecutor通過幾個核心參數來定義不同類型的線程池,適用于不同的使用場景;其中在任務提交時,會依次判斷corePoolSize, workQueque, 及maximumPoolSize,不同的狀態不同的處理。技術領域水太深,如果不是日常使用,基本一段時間后某些知識點就忘的差不多了,因此階段性地回顧與總結,對夯實自己的技術基礎很有必要。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。