1. 程式人生 > >執行緒池的使用與分析

執行緒池的使用與分析

一 關於 ThreadPoolExecutor

轉載:

https://www.cnblogs.com/dolphin0520/p/3932921.html

糾正:

1.在jdk1.8中,標識執行緒狀態的runState,用 AtomicInteger ctl 來表示。

 

二 關於其他執行緒池

1.FixedThreadPool: 

適用於為了滿足資源管理需求,而需要限制當前執行緒數量的應用場景。它適用於負載比較重的伺服器;

   (1) .如果當前執行的執行緒數小於corePoolSize,則建立新的執行緒來執行任務;

    (2).當前執行的執行緒數等於corePoolSize後,將任務加入LinkedBlockingQueue;

    (3).執行緒執行完1中的任務後,會在迴圈中反覆從LinkedBlockingQueue中獲取任務來執行;

         使用無界佇列 LinkedBlockingQueue(佇列的容量為Intger.MAX_VALUE)

2. SingleThreadExecutor

是使用單個worker執行緒的Executor,corePoolSize和maximumPoolSize都被設定為1.其他引數和FixedThreadPool相同

 適用於需要保證順序地執行各個任務並且在任意時間點,不會有多個執行緒是活動的應用場景。

(1)如果當前執行的執行緒數少於corePoolSize,則建立一個新的執行緒執行任務;

(2)當執行緒池中有一個執行的執行緒後,將任務加入LinkedBlockingQueue

(3)執行緒執行完1中的任務後,會在迴圈中反覆從LinkedBlockingQueue中獲取任務來執行;

使用無界佇列LinkedBlockingQueue佇列的容量為Intger.MAX_VALUE

3  CachedThreadPool

適用於執行很多的短期非同步任務的小程式,或者是負載較輕的伺服器;

CachedThreadPool的corePoolSize被設定為空(0),maximumPoolSize被設定為Integer.MAX.VALUE,即它是無界的,這也就意味著如果主執行緒提交任務的速度高於maximumPool中執行緒處理任務的速度時,CachedThreadPool會不斷建立新的執行緒。使用 SynchronousQueue佇列(不儲存元素的堵塞佇列)

 (1).首先向佇列提交任務(offer)。如果當前有閒執行緒正在向佇列索要任務,那麼主執行緒執行offer操作與空閒執行緒執行的poll操作配對成功,主執行緒把任務交給空閒執行緒執行,execute()方法執行完成,否則執行下面的步驟2;

(2)當初始執行緒池為空,或者maximumPool中沒有空閒執行緒時,將沒有執行緒執行poll來執行任務。這種情況下,步驟1將失敗,此時CachedThreadPool會建立新執行緒執行任務,execute方法執行完成;

  

4.ScheduledThreadPoolExecutor

適用於需要多個後臺執行週期任務,同時為了滿足資源管理需求而需要限制後臺執行緒的數量的應用場景,

主要用來在給定的延遲後執行任務,或者定期執行任務。使用的任務佇列DelayQueue(優先順序佇列)封裝了一個PriorityQueue,PriorityQueue會對佇列中的任務進行排序,執行所需時間短的放在前面先被執行(ScheduledFutureTask的time變數小的先執行),如果執行所需時間相同則先提交的任務將被先執行(ScheduledFutureTask的squenceNumber變數小的先執行)。

 (1). 當呼叫ScheduledThreadPoolExecutor的 scheduleAtFixedRate() 方法或者scheduleWirhFixedDelay() 方法時,會向ScheduledThreadPoolExecutor的 DelayQueue 新增一個實現了 RunnableScheduledFutur 介面的 ScheduledFutureTask 。

( 2 )   執行緒池中的執行緒從DelayQueue中獲取ScheduledFutureTask,然後執行任務。

 

ScheduledThreadPoolExecutor執行週期任務的步驟

1.執行緒1從DelayQueue中獲取已到期的ScheduledFutureTask(DelayQueue.take())。到期任務是指ScheduledFutureTask的time大於等於當前系統的時間;

2.執行緒1執行這個ScheduledFutureTask;

3.執行緒1修改ScheduledFutureTask的time變數為下次將要被執行的時間;

4.執行緒1把這個修改time之後的ScheduledFutureTask放回DelayQueue中(DelayQueue.add())。

5.弊端

 Executors 返回執行緒池物件的弊端如下:

        FixedThreadPool 和 SingleThreadExecutor : 允許請求的佇列長度為 Integer.MAX_VALUE,可能堆積大量的請求,從而導致OOM。

        CachedThreadPool 和 ScheduledThreadPool : 允許建立的執行緒數量為 Integer.MAX_VALUE ,可能會建立大量執行緒,從而導致OOM。