在ThreadPoolExecutor類中有4個構造函數,最終調用的是如下函數:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
構造函數一共有7個參數,如下:
corePoolSize
線程池中的核心線程數,當提交一個任務時,線程池創建一個新線程執行任務,直到當前線程數等於corePoolSize;如果當前線程數為corePoolSize,繼續提交的任務被保存到阻塞隊列中,等待被執行;如果執行了線程池的prestartAllCoreThreads()方法,線程池會提前創建並啟動所有核心線程。當線程數小於等於corePoolSize時,默認情況下線程會一直存活在線程池中,即時線程處於空閑狀態。如果allowCoreThreadTimeOut被設置為true時,無論線程數多少,那么線程處於空閑狀態超過一定時間就會被銷毀掉。
maximumPoolSize
線程池中允許的最大線程數。如果當前阻塞隊列滿了,且繼續提交任務,則創建新的線程執行任務,前提是當前線程數小於maximumPoolSize;
keepAliveTime
線程空閑時的存活時間,即當線程沒有任務執行時,繼續存活的時間;默認情況下,該參數只在線程數大於corePoolSize時才有用;如果allowCoreThreadTimeOut被設置為true時,無論線程數多少,線程處於空閑狀態超過一定時間就會被銷毀掉。
unit
keepAliveTime的單位。TimeUnit是一個枚舉類型,其包括:
- NANOSECONDS :1微毫秒 = 1微秒 / 1000
- MICROSECONDS :1微秒 = 1毫秒 / 1000
- MILLISECONDS :1毫秒 = 1秒 /1000
- SECONDS :秒
- MINUTES :分
- HOURS :小時
- DAYS :天
workQueue
用來保存等待被執行的任務的阻塞隊列,且任務必須實現Runable接口,如下阻塞隊列:
- ArrayBlockingQueue:基於數組結構的有界阻塞隊列,按FIFO排序任務;
- LinkedBlockingQuene:基於鏈表結構的無界阻塞隊列,按FIFO排序任務,吞吐量通常要高於ArrayBlockingQuene;
- SynchronousQuene:一個不存儲元素的阻塞隊列,每個插入操作必須等到另一個線程調用移除操作,否則插入操作一直處於阻塞狀態,吞吐量通常要高於LinkedBlockingQuene;
threadFactory
創建線程的工廠,通過自定義的線程工廠可以給每個新建的線程設置一個具有識別度的線程名,比如:
public class OneMoreThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
public OneMoreThreadFactory() {
namePrefix = "OneMoreThread-" + poolNumber.getAndIncrement() + "-";
}
@Override
public Thread newThread(Runnable r) {
return new Thread( r, namePrefix + threadNumber.getAndIncrement());
}
}
handler
線程池的飽和策略,當阻塞隊列滿了,且沒有空閑的工作線程,如果繼續提交任務,必須采取一種策略處理該任務,線程池提供了4種策略:
- AbortPolicy:直接拋出異常,默認策略;
- CallerRunsPolicy:用調用者所在的線程來執行任務;
- DiscardOldestPolicy:丟棄阻塞隊列中靠最前的任務,並執行當前任務;
- DiscardPolicy:直接丟棄任務;