java多線程(線程池):ThreadPoolExecutor構造方法詳解

1.爲什麼我們需要了解ThreadPoolExecutor?

          java的併發包爲我們提供了一個Executors(java.util.concurrent)工具類,通過這個工具類我們可以很方便的創建線程池,其中:

    (1).創建無界線程池

       

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

 

  (2).創建有界線程池

 public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

(3).創建單一線程池

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

上述三個創建線程池的方法均用到了ThreadPoolExecutor的構造方法(還有很多地方沒有一一列出):

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

所以瞭解此構造方法是非常有必要的。

2.該構造方法的參數解釋如下:

corePoolSize:線程池中保存的線程數,包括空閒線程,也就是核心池的大小。
maximumPoolSize:線程池允許的最大線程數。
keepAliveTime:當線程數量大於corePoolSize值時,在沒有超過指定時間時不從線程池中將空閒的線程刪除,
               如果超過了指定的時間則會被刪除。
unit:keepAliveTime的時間單位。
workQueue:執行前用於保存任務的隊列。此隊列僅保持由execute提交的runnable任務。

在線程的使用過程中基本遵循如下論據:

       (1).如果欲執行的任務(也就是調用:executorService.execute(Runnable r)的次數)小於線程核心池的大小,那麼任務並不會被放入擴展隊列queue中,同時其他參數可以忽略。

       (2).如果欲執行的任務大於線程核心池的大小但不大於線程池允許的最大線程數,同時使用單向鏈表阻塞隊列(LinkedBlockingQueue)來當做workQueue的話,線程池此時將核心池能容納的最大值剩下的任務存入隊列中,此時可以忽略keepAliveTime和timeUnit這兩個參數。

       (3).如果欲執行的任務大於線程核心池的大小但不大於線程池允許的最大線程數,同時使用同步阻塞隊列(SynchronousQueue)來當作workQueue的話,keepAlive與timeUnit這兩個參數有效,但此時不會將線程池此時將核心池能容納的最大值剩下的任務存入隊列(SynchronousQueue同步阻塞隊列)中而是馬上創建線程將多餘的任務執行,當執行完成並且超過了keepAliveTime以後將多餘的任務清除。

      (4).如果欲執行的任務大於線程核心池的大小同時大於線程池允許的最大線程數,同時使用單向鏈表阻塞隊列(LinkedBlockingQueue)來當作workQueue的話,線程池此時將核心池能容納的最大值剩下的任務存入隊列中,此時可以忽略keepAliveTime、timeUnit、maximumPoolSize這三個參數。

      (5).如果欲執行的任務大於線程核心池的大小同時大於線程池允許的最大線程數,同時使用同步阻塞隊列(SynchronousQueue)來當作workQueue的話,此時會有maximumPoolSize個線程執行任務,同時不再處理剩下的任務,拋出異常。

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