1. 程式人生 > 其它 >執行緒池基本內容(1)

執行緒池基本內容(1)

執行緒池主要解決兩個問題:

  1.當執行大量非同步任務時執行緒池能夠提供較好的效能。在不使用執行緒池時,每當需要執行非同步任務時直接new一個執行緒來執行,而執行緒的建立和銷燬是需要開銷的。執行緒池裡面的執行緒是可複用的,不需要每次執行非同步任務時都重新建立和銷燬執行緒。

  2.執行緒池提供了一種資源限制和管理的手段,比如可以限制執行緒的個數,動態新增執行緒等。另外,它也保留了一些基本的統計資料,比如當前執行緒池完成的任務數目等。

建立執行緒池的引數有哪些?

  ThreadPoolExecutor提供了四個建構函式:

  

//五個引數的建構函式
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue)

//六個引數的建構函式-1
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory)

//六個引數的建構函式-2
public ThreadPoolExecutor(int corePoolSize,
                          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)

 

  int corePoolSize :執行緒池核心執行緒個數。執行緒池新建執行緒的時候,如果當前執行緒總數小於corePoolSize,則新建的是核心執行緒,如果超過corePoolSize,則新建的是非核心執行緒。

  int maximumPoolSize:執行緒池最大執行緒數量。是 核心執行緒數 與 非核心執行緒數 的和。如果佇列滿了,並且已建立的執行緒數小於最大執行緒數,則執行緒池會再建立新的執行緒執行任務。值得注意的是,如果使用了無界的任務佇列這個引數就沒什麼效果。

  workQueue(任務佇列):用於儲存等待執行的任務的阻塞佇列。當所有的核心執行緒都在幹活時,新新增的任務會被新增到這個佇列中等待處理,如果佇列滿了,則新建非核心執行緒執行任務。

  常用的workQueue型別:

  • SynchronousQueue這個佇列接收到任務的時候,會直接提交給執行緒處理,而不保留它,如果所有執行緒都在工作怎麼辦?那就新建一個執行緒來處理這個任務!所以為了保證不出現<執行緒數達到了maximumPoolSize而不能新建執行緒>的錯誤,使用這個型別佇列的時候,maximumPoolSize一般指定成Integer.MAX_VALUE,即無限大 。

  • LinkedBlockingQueue這個佇列接收到任務的時候,如果當前執行緒數小於核心執行緒數,則新建執行緒(核心執行緒)處理任務;如果當前執行緒數等於核心執行緒數,則進入佇列等待。由於這個佇列沒有最大值限制,即所有超過核心執行緒數的任務都將被新增到佇列中,這也就導致了maximumPoolSize的設定失效,因為匯流排程數永遠不會超過corePoolSize 。

  • ArrayBlockingQueue可以限定佇列的長度,接收到任務的時候,如果沒有達到corePoolSize的值,則新建執行緒(核心執行緒)執行任務,如果達到了,則入隊等候,如果佇列已滿,則新建執行緒(非核心執行緒)執行任務,又如果匯流排程數到了maximumPoolSize,並且佇列也滿了,則發生錯誤 。


  long keepAliveTime(執行緒活動保持時間):非核心執行緒處於閒置狀態所能存活的時長。   TimeUnit(執行緒活動保持時間的單位):可選的單位有天(DAYS)、小時(HOURS)、分鐘(MINUTES)、毫秒(MILLISECONDS)、微秒(MICROSECONDS,千分之一毫秒)和納秒(NANOSECONDS,千分之一微秒)。   ThreadFactory:建立執行緒的工廠。   RejectExecutionHandler(飽和策略):佇列和執行緒池都滿了,說明此時執行緒池處於飽和狀態,那麼必須採取一種策略處理提交的新任務。這個策略預設情況下是 AbortPolicy,表示無法處理新任務時丟擲異常。   Java 執行緒池框架提供了以下 4 種策略:     ThreadPoolExecutor.AbortPolicy:丟棄任務並丟擲RejectedExecutionException異常。這是執行緒池預設的拒絕策略,在任務不能再提交的時候,丟擲異常,及時反饋程式執行狀態。     ThreadPoolExecutor.DiscardPolicy:丟棄任務,但是不丟擲異常。如果執行緒佇列已滿,則後續提交的任務都會被丟棄。     ThreadPoolExecutor.DiscardOldestPolicy:丟棄佇列最前面的任務,然後重新提交被拒絕的任務。     ThreadPoolExecutor.CallerRunsPolicy:由呼叫執行緒(提交任務的執行緒)處理該任務。   

參考文獻:執行緒池,這一篇或許就夠了 - 簡書 (jianshu.com)