java線程池——ThreadPoolExecutor源碼解析

在Java中,咱們常常使用的線程池就是ThreadPoolExecutor,此外還有定時的線程池ScheduledExecutorService(),可是須要注意的是Executors.newCachedThreadPool()的線程是沒有上屆的,在使用時,須要注意,由於沒有辦法控制線程數量,可能會致使線程的溢出。
一個簡單的示例函數

clipboard.png

1 ThreadPoolExecutor提供了四個構造函數:
//五個參數的構造函數
public ThreadPoolExecutor(int corePoolSize,spa

int maximumPoolSize,
                      long keepAliveTime,
                      TimeUnit unit,
                      BlockingQueue<Runnable> workQueue)

//六個參數的構造函數
public ThreadPoolExecutor(int corePoolSize,線程

int maximumPoolSize,
                      long keepAliveTime,
                      TimeUnit unit,
                      BlockingQueue<Runnable> workQueue,
                      ThreadFactory threadFactory)

//六個參數的構造函數
public ThreadPoolExecutor(int corePoolSize,code

int maximumPoolSize,
                      long keepAliveTime,
                      TimeUnit unit,
                      BlockingQueue<Runnable> workQueue,
                      RejectedExecutionHandler handler)

//七個參數的構造函數
public ThreadPoolExecutor(int corePoolSize,對象

int maximumPoolSize,
                      long keepAliveTime,
                      TimeUnit unit,
                      BlockingQueue<Runnable> workQueue,
                      ThreadFactory threadFactory,
                      RejectedExecutionHandler handler)

2 各個參數解釋接口

  • int corePoolSize:該線程池中核心線程數最大值。

核心線程:線程池新建線程的時候,若是當前線程總數小於corePoolSize,則新建的是核心線程,若是超過corePoolSize,則新建的線程即爲非核心線程,核心線程默認狀況下會一直存在線程池中,即便這個線程什麼也不幹,若是指定ThreadPoolExecutor的allowCoreThreadTimeOut這個屬性是true,那麼核心線程若是長時間不幹活的話,超過必定時間,就會被銷燬掉。隊列

  • int maximumPoolSize:該線程池中線程的最大值
  • long keepAliveTime :該線程池中非核心線程閒置超時時間

一個非核心線程,若是不幹活的時間超過這個參數所設定的時長,就會被銷燬,若是設置allowCoreThreadTimeOut = true,那麼核心線程超過所設定的時長,那麼也會銷燬掉。ip

  • TimeUnit unit:keepAliveTime的單位

TimeUnit是一個枚舉類型,其包括:NANOSECONDS : 1微毫秒 = 1微秒 / 1000,MICROSECONDS : 1微秒 = 1毫秒 / 1000,MILLISECONDS : 1毫秒 = 1秒 /1000,
SECONDS : 秒,MINUTES : 分,HOURS : 小時,DAYS : 天。it

  • BlockingQueue workQueue:該線程池中的任務隊列:維護等待執行的Runnable對象。

若是當全部的核心線程都在幹活時,新添加的任務會被添加到這個隊列中等待處理,若是隊列滿了,則新建非核心的線程執行任務。經常使用的workQueue類型。io

    • SynchronousQueue:這個隊列接收到任務的時候,會直接提交給線程處理,而不會保留它,若是線程都在工做,那就新建一個線程來處理這個任務,因此爲了保證不出現<線程數達到了maximumPoolSize而不能新建線程>的錯誤,使用這個類型隊列的時候,maximumPoolSize通常指定成Integer.MAX_VALUE,即無限大。
    • LinkedBlockingQueue:這個隊列接收到任務的時候,若是線程小於核心線程,則新建核心線程來處理任務,若是當前線程等於核心線程數,則進入隊列中等待。因爲這個隊列沒有最大值限制,即全部超過核心線程數的任務都會被添加到隊列中去,這也致使maximumPoolSize的設定失效,由於總線程數永遠不會超過corePoolSize
    • ArrayBlockingQueue:能夠設定隊列的長度,接收到任務的時候,若是沒有達到corePoolSize的值,則新建線程執行任務,若是達到了,則入隊等候,若是隊列已滿,則新建線程執行任務,若是線程數到了maximumPoolSize,而且隊列中也滿了,則發生錯誤。
    • DelayQueue:隊列中元素必須實現Delayed接口,這就意味着你傳進去的任務必須實現

Delayed接口,這個隊列接收到任務時,首先先入隊,只有達到指定的延時時間,纔會執行任務。

    • ThreadFactory threadFactory:建立線程的方式,這是一個接口,你new它的時候須要實現它的Thread newThread(Runnable r)方法,通常用不上。
    • RejectedExecutionHandler handler:這玩意兒就是拋出異常專用的,好比上面提到的兩個錯誤發生了,就會由這個handler拋出異常,根本用不上。

3 經常使用API解釋:

  • public void execute(Runnable command)

未來某個時候執行給定的任務。任務能夠在新線程中執行,也能夠在現有的池線程中執行。若是沒法提交任務以供執行,或者由於該執行器已經關閉,或者由於其容量已經達到,則該任務由當前{RejectedExecutionHandler}處理。

  • public void shutdown()

將線程池狀態置爲SHUTDOWN,並不會當即中止,中止接收外部submit的任務,內部正在跑的任務和隊列裏等待的任務,會執行完,才真正中止。

  • public List<Runnable> shutdownNow()

將線程池狀態置爲STOP。企圖當即中止,事實上不必定,跟shutdown()同樣,先中止接收外部提交的任務,忽略隊列裏等待的任務,嘗試將正在跑的任務interrupt中斷,返回未執行的任務列表。

  • public boolean awaitTermination(long timeout, TimeUnit unit)

當前線程阻塞,直到等全部已提交的任務(包括正在跑的和隊列中等待的)執行完,或者等超時時間到,或者線程被中斷,拋出InterruptedException,而後返回true(shutdown請求後全部任務執行完畢)或false(已超時)。

相關文章
相關標籤/搜索