Executor框架

概述:java

  • Eexecutor做爲靈活且強大的異步執行框架,其支持多種不一樣類型的任務執行策略
  • 提供了一種標準的方法將任務的提交過程和執行過程解耦開發
  • 基於生產者-消費者模式,其提交任務的線程至關於生產者,執行任務的線程至關於消費者,並用Runnable來表示任務
  • Executor的實現還提供了對生命週期的支持,以及統計信息收集,應用程序管理機制和性能監視等機制。

Executor的UML圖:數組

  • Executor:一個接口,其定義了一個接收Runnable對象的方法executor,其方法簽名爲executor(Runnable command),
  • ExecutorService:是一個比Executor使用更普遍的子類接口,其提供了生命週期管理的方法,以及可跟蹤一個或多個異步任務執行情況返回Future的方法
  • AbstractExecutorService:ExecutorService執行方法的默認實現
  • ScheduledExecutorService:一個可定時調度任務的接口
  • ScheduledThreadPoolExecutor:ScheduledExecutorService的實現,一個可定時調度任務的線程池
  • ThreadPoolExecutor:線程池,能夠經過調用Executors如下靜態工廠方法來建立線程池並返回一個ExecutorService對象

阿里發佈的 Java開發手冊中強制線程池不容許使用 Executors 去建立,而是經過 ThreadPoolExecutor 的方式,這樣的處理方式讓寫的同窗更加明確線程池的運行規則,規避資源耗盡的風險緩存

參數說明:框架

  • corePoolSize:核心線程數,若是運行的線程少於corePoolSize,則建立新線程來執行新任務,即便線程池中的其餘線程是空閒的
  • maximumPoolSize:最大線程數,可容許建立的線程數,corePoolSize和maximumPoolSize設置的邊界自動調整池大小:
  • corePoolSize <運行的線程數< maximumPoolSize:僅當隊列滿時才建立新線程
  • corePoolSize=運行的線程數= maximumPoolSize:建立固定大小的線程池
  • keepAliveTime:若是線程數多於corePoolSize,則這些多餘的線程的空閒時間超過keepAliveTime時將被終止
  • unit:keepAliveTime參數的時間單位
  •  workQueue:保存任務的阻塞隊列,與線程池的大小有關:
  •   當運行的線程數少於corePoolSize時,在有新任務時直接建立新線程來執行任務而無需再進隊列
  •   當運行的線程數等於或多於corePoolSize,在有新任務添加時則選加入隊列,不直接建立線程
  •   當隊列滿時,在有新任務時就建立新線程
  • threadFactory:使用ThreadFactory建立新線程,默認使用defaultThreadFactory建立線程
  • handle:定義處理被拒絕任務的策略,默認使用ThreadPoolExecutor.AbortPolicy,任務被拒絕時將拋出RejectExecutorException

newFixedThreadPool異步

  • 建立可重用且固定線程數的線程池,若是線程池中的全部線程都處於活動狀態,此時再提交任務就在隊列中等待,直到有可用線程
  • 若是線程池中的某個線程因爲異常而結束時,線程池就會再補充一條新線程

newSingleThreadExecutor性能

  • 建立一個單線程的Executor,若是該線程由於異常而結束就新建一條線程來繼續執行後續的任務

newScheduledThreadPoolspa

  • 建立一個可延遲執行或按期執行的線程池
  • 使用newScheduledThreadPool來模擬心跳機制

newCachedThreadPool線程

  • 建立可緩存的線程池,若是線程池中的線程在60秒未被使用就將被移除
  • 在執行新的任務時,當線程池中有以前建立的可用線程就重用可用線程,不然就新建一條線程

Executor的生命週期rest

  • ExecutorService提供了管理Eecutor生命週期的方法
  • ExecutorService的生命週期包括了:運行  關閉和終止三種狀態
  • ExecutorService在初始化建立時處於運行狀態。對象

    shutdown方法等待提交的任務執行完成並再也不接受新任務,在完成所有提交的任務後關閉

    shutdownNow方法將強制終止全部運行中的任務並再也不容許提交新任務

ExecutorCompletionService

  • 實現了CompletionService,將執行完成的任務放到阻塞隊列中,經過take或poll方法來得到執行結果

  • 輸出結果:

關注點1 :線程池大小

  • 線程池有兩個線程數的設置,一個爲核心池線程數,一個爲最大線程數。
  • 在建立了線程池後,默認狀況下,線程池中並無任何線程,等到有任務來才建立線程去執行任務,除非調用了prestartAllCoreThreads()或者prestartCoreThread()方法
  • 當建立的線程數等於 corePoolSize 時,會加入設置的阻塞隊列。當隊列滿時,會建立線程執行任務直到線程池中的數量等於maximumPoolSize

關注點2 :適當的阻塞隊列

  • java.lang.IllegalStateException: Queue full
  • 方法 拋出異常 返回特殊值 一直阻塞 超時退出
  • 插入方法 add(e) offer(e) put(e) offer(e,time,unit)
  • 移除方法 remove() poll() take() poll(time,unit)
  • 檢查方法 element() peek() 不可用 不可用
  • ArrayBlockingQueue :一個由數組結構組成的有界阻塞隊列。
  • LinkedBlockingQueue :一個由鏈表結構組成的有界阻塞隊列。
  • PriorityBlockingQueue :一個支持優先級排序的無界阻塞隊列。
  • DelayQueue: 一個使用優先級隊列實現的無界阻塞隊列。
  • SynchronousQueue: 一個不存儲元素的阻塞隊列。
  • LinkedTransferQueue: 一個由鏈表結構組成的無界阻塞隊列。
  • LinkedBlockingDeque: 一個由鏈表結構組成的雙向阻塞隊列。

關注點3 :明確拒絕策略

  • ThreadPoolExecutor.AbortPolicy: 丟棄任務並拋出RejectedExecutionException異常。 (默認)
  • ThreadPoolExecutor.DiscardPolicy:也是丟棄任務,可是不拋出異常。
  • ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊列最前面的任務,而後從新嘗試執行任務(重複此過程)
  • ThreadPoolExecutor.CallerRunsPolicy:由調用線程處理該任務

說明:Executors 各個方法的弊端:

  • 1)newFixedThreadPool 和 newSingleThreadExecutor:
    • 主要問題是堆積的請求處理隊列可能會耗費很是大的內存,甚至 OOM。
  • 2)newCachedThreadPool 和 newScheduledThreadPool:
    • 主要問題是線程數最大數是 Integer.MAX_VALUE,可能會建立數量很是多的線程,甚至 OOM。
相關文章
相關標籤/搜索