九、Executor框架

  • 2019 年 10 月 21 日
  • 筆記

Executor框架

​ 我們知道執行緒池就是執行緒的集合,執行緒池集中管理執行緒,以實現執行緒的重用,降低資源消耗,提高響應速度等。執行緒用於執行非同步任務,單個的執行緒既是工作單元也是執行機制,從JDK1.5開始,為了把工作單元與執行機制分離開,Executor框架誕生了,他是一個用於統一創建與運行的介面。Executor框架實現的就是執行緒池的功能。

【1】Executor框架結構圖解

1、Executor框架包括3大部分:

(1)任務。也就是工作單元,包括被執行任務需要實現的介面:Runnable介面或者Callable介面;

(2)任務的執行。也就是把任務分派給多個執行緒的執行機制,包括Executor介面及繼承自Executor介面的ExecutorService介面。

(3)非同步計算的結果。包括Future介面及實現了Future介面的FutureTask類。

Executor框架的成員及其關係可以用一下的關係圖表示:

img

2、Executor框架的使用示意圖:

img

3、Executor框架成員:

img

【2】ThreadPoolExecutor實現類

1、FixedThreadPool

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

FixedThreadPool是執行緒數量固定的執行緒池,適用於為了滿足資源管理的需求,而需要適當限制當前執行緒數量的情景,適用於負載比較重的伺服器。

可以看出它的實現就是把執行緒池最大執行緒數量maxmumPoolSize和核心執行緒池的數量corePoolSize設置為相等,並且使用LinkedBlockingQueue作為阻塞隊列,那麼首先可以知道執行緒池的執行緒數量最多就是nThread,只會在核心執行緒池階段創建,此外,因為LinkedBlockingQueue是無限的雙向隊列,因此當任務不能立刻執行時,都會添加到阻塞隊列中

注意:因為阻塞隊列是無限的雙向隊列,因此如果沒有調用shutDownNow()或者shutDown()方法,執行緒池是不會拒絕任務的,如果執行緒池中的執行緒一直被佔有,且不斷有請求到來,會導致大量的請求堆積,進而造成記憶體溢出系統崩潰。

2、SingleThreadExecutor

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

SingleThreadExecutor是只有一個執行緒的執行緒池,常用於需要讓執行緒順序執行,並且在任意時間,只能有一個任務被執行,而不能有多個執行緒同時執行的場景。

3、CachedThreadPool

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

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

CachedThreadPool使用SynchronizedQueue作為阻塞隊列,SynchronizedQueue是不存儲元素的阻塞隊列,實現「一對一的交付」,也就是說,每次向隊列中put一個任務必須等有執行緒來take這個任務,否則就會一直阻塞該任務,如果一個執行緒要take一個任務就要一直阻塞知道有任務被put進阻塞隊列。

【3】ScheduledThreadPoolExecutor實現類

具體參見:點擊打開連接

【4】Future介面/FutureTask實現類

具體參見:點擊打開連接