1. 程式人生 > >Java併發程式設計的藝術(十一)——執行緒池(2)

Java併發程式設計的藝術(十一)——執行緒池(2)

這裡寫圖片描述

Executor兩級排程模型

title
在HotSpot虛擬機器中,Java中的執行緒將會被一一對映為作業系統的執行緒。
在Java虛擬機器層面,使用者將多個任務提交給Executor框架,Executor負責分配執行緒執行它們;
在作業系統層面,作業系統再將這些執行緒分配給處理器執行。

Executor結構

title
Executor框架中的所有類可以分成三類:

  1. 任務
    任務有兩種型別:Runnable和Callable。
  2. 任務執行器
    Executor框架最核心的介面是Executor,它表示任務的執行器。
    Executor的子介面為ExecutorService。
    ExecutorService有兩大實現類:ThreadPoolExecutor和ScheduledThreadPoolExecutor。

  3. 執行結果
    Future介面表示非同步的執行結果,它的實現類為FutureTask。

執行緒池

Executors工廠類可以建立四種類型的執行緒池,通過Executors.newXXX即可建立。

1. FixedThreadPool

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

title

  • 它是一種固定大小的執行緒池;
  • corePoolSize和maximunPoolSize都為使用者設定的執行緒數量nThreads;
  • keepAliveTime為0,意味著一旦有多餘的空閒執行緒,就會被立即停止掉;但這裡keepAliveTime無效;
  • 阻塞佇列採用了LinkedBlockingQueue,它是一個無界佇列;
  • 由於阻塞佇列是一個無界佇列,因此永遠不可能拒絕任務;
  • 由於採用了無界佇列,實際執行緒數量將永遠維持在nThreads,因此maximumPoolSize和keepAliveTime將無效。

2. CachedThreadPool

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

title

  • 它是一個可以無限擴大的執行緒池;
  • 它比較適合處理執行時間比較小的任務;
  • corePoolSize為0,maximumPoolSize為無限大,意味著執行緒數量可以無限大;
  • keepAliveTime為60S,意味著執行緒空閒時間超過60S就會被殺死;
  • 採用SynchronousQueue裝等待的任務,這個阻塞佇列沒有儲存空間,這意味著只要有請求到來,就必須要找到一條工作執行緒處理他,如果當前沒有空閒的執行緒,那麼就會再建立一條新的執行緒。

3. SingleThreadExecutor

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

title

  • 它只會建立一條工作執行緒處理任務;
  • 採用的阻塞佇列為LinkedBlockingQueue;

4. ScheduledThreadPool

它用來處理延時任務或定時任務。
title

  • 它接收SchduledFutureTask型別的任務,有兩種提交任務的方式:

    1. scheduledAtFixedRate
    2. scheduledWithFixedDelay
  • SchduledFutureTask接收的引數:

    1. time:任務開始的時間
    2. sequenceNumber:任務的序號
    3. period:任務執行的時間間隔
  • 它採用DelayQueue儲存等待的任務

    • DelayQueue內部封裝了一個PriorityQueue,它會根據time的先後時間排序,若time相同則根據sequenceNumber排序;
    • DelayQueue也是一個無界佇列;
  • 工作執行緒的執行過程:

    • 工作執行緒會從DelayQueue取已經到期的任務去執行;
    • 執行結束後重新設定任務的到期時間,再次放回DelayQueue

這裡寫圖片描述