[Java基礎知識] Java線程池

首先我們想一想爲什麼我們要使用線程池呢?這裏主要我們可以給出以下原因:

  1. 如果創建線程的頻率很高,每次處理的時間會很短,這時我們頻繁的創建和銷燬線程會造成巨大的開銷。
  2. 其次如果每次需要一個線程就創建一個線程,我們管理線程將會很不方便。

上面就是我們在開發時需要考慮的是否要使用線程池的因素。

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()的創建的線程池是如何實現延遲的。
未完待續

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章