首先我們想一想爲什麼我們要使用線程池呢?這裏主要我們可以給出以下原因:
- 如果創建線程的頻率很高,每次處理的時間會很短,這時我們頻繁的創建和銷燬線程會造成巨大的開銷。
- 其次如果每次需要一個線程就創建一個線程,我們管理線程將會很不方便。
上面就是我們在開發時需要考慮的是否要使用線程池的因素。
Java使用Executors通過靜態工廠方法提供了四種線程池:
Executors.newCachedThreadPool() 創建一個無大小限制的線程池,只要需要創建新的線程則立即創建。每個線程如果在60秒內
沒有處理的則會銷燬。
Executors.newFixedThreadPool() 創建一個固定大小的線程池。
Executors.newScheduledThreadPool() 創建一個延期執行的線程池。
Executors.newSingleThreadExecutor() 創建一個只有一個線程的線程池。
觀察上面的幾個方法的實現,會發現都創建了一個ThreadPoolExecutor對象。下面我們分別分析Executors的這些靜態工廠方法的實現。
首先來看一下ThreadPoolExecutor()的構造函數:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
corePoolSize:線程池中線程的數量,這些線程就算處於空閒狀態也不會回收
maximumPoolSize:線程池中允許的線程的最大數量
keepAliveTime:超過corePoolSize數量的線程的最大存活時間
unit:KeepAliveTime的時間單位
workQueue:用於存放execute方法提交的任務
newCachedThreadPool()
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
我們可以注意到newCachedThreadPool()創建的是一個初始線程數爲0,線程池中線程數最多爲整數類型的最大線程數,空閒線程存活時間爲60s的線程池。
newFixedThreadPool()
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
同樣可以注意到newFixedThreadPool()創建的是一個初始線程數和最大線程數(nThreads)相等的線程池。
newScheduledThreadPool()
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
new ScheScheduledThreadPoolExecutor(corePoolSize)的實現如下:
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
newScheduledThreadPool()首先調用ScheduledThreadPoolExecutor(),然後ScheduledThreadPoolExecutor()再調用ThreadPoolExecutor()構造函數。創建了一個初始線程數爲corePoolSize,最大線程數爲整數的最大值,超過corePoolSize的空閒線程立即銷燬的線程池。
newSingleThreadExecutor()
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
由上面的代碼我們可以發現newSingleThreadExecutor()創建的是一個初試線程數和最大線程數都爲1的線程。
閱讀到這裏你可能疑惑newScheduledThreadPool()的創建的線程池是如何實現延遲的。
未完待續