線程池的 7 大參數整理。
public ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize 線程池中長期存活的線程數
ThreadPoolExecutor 在創建之初,是不會立即初始化corePoolSize數量的Thread的,而是通過外部request來一個一個的創建,當達到corePoolSize數目之后,就會維持至少corePoolSize數目的Thread在pool中,哪怕他們都處于空閑狀態(idle)。corePoolSize >= 0。
maximumPoolSize 線程池中的最大線程數量
maximumPoolSize >= corePoolSize,maximumPoolSize>0
- 若當前線程池中線程數 < corePoolSize,則每來一個任務就創建一個線程去執行。
- 若當前線程池中線程數 >= corePoolSize,會嘗試將任務添加到任務隊列。如果添加成功,則任務會等待空閑線程將其取出并執行(針對的是有界隊列)。
- 若隊列已滿,且當前線程池中線程數 < maximumPoolSize,創建新的線程。
- 若當前線程池中線程數 >= maximumPoolSize,則會采用拒絕策略。
keepAliveTime 空閑線程存活時間
當線程池線程數量超過corePoolSize時,多余的空閑線程會在多長時間內被銷毀。
銷毀的線程數=maximumPoolSize(最大線程數)-corePoolSize(核心線程數)。
TimeUnit 時間單位
空閑線程存活時間的描述單位,有以下選項:
- TimeUnit.DAYS:天
- TimeUnit.HOURS:小時
- TimeUnit.MINUTES:分
- TimeUnit.SECONDS:秒
- TimeUnit.MILLISECONDS:毫秒
- TimeUnit.MICROSECONDS:微妙
- TimeUnit.NANOSECONDS:納秒
BlockingQueue
提交但未執行的任務隊列,有以下選項:
- LinkedBlockingQueue:用鏈表實現的隊列,可以是有界的,也可以是無界的,但在Executors中默認使用無界的。當有新的任務來到時,若系統的線程數小于corePoolSize,線程池會創建新的線程執行任務, 當系統的線程數量等于corePoolSize后,因為是無界的任務隊列,總是能成功將任務添加到任務隊列中,所以線程數量不再增加。若任務創建的速度遠大于任務處理的速度,無界隊列會快速增長,直到內存耗盡。
- SynchronousQueue:一個不存儲元素的阻塞隊列,SynchronousQueue沒有容量,所以實際上提交的任務不會被添加到任務隊列,總是將新任務提交給線程執行,如果沒有空閑的線程,則嘗試創建新的線程,如果線程數量已經達到最大值(maximumPoolSize),則執行拒絕策略。
- ArrayBlockingQueue:一個由數組結構組成的有界阻塞隊列。
- PriorityBlockingQueue:一個支持優先級排序的無界阻塞隊列。
- DelayQueue:一個使用優先級隊列實現的無界阻塞隊列,只有在延遲期滿時才能從中提取元素。
- LinkedTransferQueue:一個由鏈表結構組成的無界阻塞隊列。與SynchronousQueue類似,還含有非阻塞方法。
- LinkedBlockingDeque:一個由鏈表結構組成的雙向阻塞隊列。
ThreadFactory 創建線程的工廠
線程池創建線程時調用的工廠方法,通過此方法可以設置線程的優先級、線程命名規則以及線程類型(用戶線程還是守護線程)等。一般情況下使用默認的,即Executors類的靜態方法defaultThreadFactory(),也可以自定義。
import JAVA.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Test {
public static void mAIn(String[] args) {
// 創建線程工廠
ThreadFactory threadFactory = new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
// 創建線程池中的線程
Thread thread = new Thread(runnable);
// 設置線程名稱
thread.setName("Thread-" + runnable.hashCode());
// 設置線程優先級(最大值:10)
thread.setPriority(Thread.MAX_PRIORITY);
//......
return thread;
}
};
// 創建線程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
5,
10,
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(10),
threadFactory
);
try{
threadPoolExecutor.submit(new Runnable() {
@Override
public void run() {
Thread thread = Thread.currentThread();
System.out.println(String.format("線程:%s,線程優先級:%d",thread.getName(), thread.getPriority()));
}
});
}catch (Exception e) {
} finally {
threadPoolExecutor.shutdown();
}
}
}
Executors.defaultThreadFactory()
RejectedExecutionHandler
拒絕策略。當線程池的任務超出線程池隊列可以存儲的最大值之后,執行的策略。
- AbortPolicy策略:直接拋出異常,阻止系統正常工作。(線程池的默認策略)。
- DiscardOldestPolicy策略:丟棄任務隊列中最早添加的任務,并嘗試提交當前任務。
- CallerRunsPolicy策略:調用主線程執行被拒絕的任務,這提供了一種簡單的反饋控制機制,將降低新任務的提交速度。
- DiscardPolicy策略:忽略并拋棄當前任務。
new一個線程池