JDK5中的concurrent包簡介

concurrent併發包裏面幾個重要的接口有:Executor、ExecutorService, ScheduledExecutorService
重要的實現類有:ScheduledThreadPoolExecutor, ThreadPoolExecutor
關於這幾個接口和實現類的類圖可以參見文檔最後的UML圖,圖中對一些比較重要的屬性、方法進行紅色標識,可以重點關注;

先來說說java.util.concurrent.ThreadPoolExecutor ,也就是我們經常說到的線程池,通過該類,應用可以直接拿來使用,只要在初始化時設置不同的參數即可;其主要的參數有以下幾個:

  • corePoolSize : 線程池維護線程的最少數量
  • maximumPoolSize :線程池維護線程的最大數量
  • keepAliveTime : 線程池維護線程所允許的空閒時間
  • unit : 線程池維護線程所允許的空閒時間的單位
  • workQueue : 線程池所使用的緩衝隊列
  • handler : 線程池對拒絕任務的處理策略

一個任務通過execute(Runnable)方法被添加到線程池,任務就是一個 Runnable類型的對象,任務的執行方法就是Runnable類型對象的run()方法;注意:是Runnable,而不是Thread

當一個任務通過execute(Runnable)方法欲添加到線程池時:

  • 如果此時線程池中的數量小於corePoolSize,即使線程池中的線程都處於空閒狀態,也要創建新的線程來處理被添加的任務。
  • 如果此時線程池中的數量等於corePoolSize,但是緩衝隊列workQueue未滿,那麼任務被放入緩衝隊列。
  • 如果此時線程池中的數量大於corePoolSize,緩衝隊列workQueue滿,並且線程池中的數量小於maximumPoolSize,建新的線程來處理被添加的任務。
  • 如果此時線程池中的數量大於corePoolSize,緩衝隊列workQueue滿,並且線程池中的數量等於maximumPoolSize,那麼通過handler所指定的策略來處理此任務。
  • 從上面可以看出線程池中處理任務的優先級爲:
    核心線程corePoolSize、任務隊列workQueue、最大線程maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務。

當線程池中的線程數量大於 corePoolSize時,如果某線程空閒時間超過keepAliveTime,線程將被終止。這樣,線程池可以動態的調整池中的線程數。

unit可選的參數爲java.util.concurrent.TimeUnit中的幾個靜態屬性:
NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。

默認handler有四個選擇,當然也可以自行擴展,但是要特別小心:

  • ThreadPoolExecutor.AbortPolicy:直接拋出java.util.concurrent.RejectedExecutionException異常;
  • ThreadPoolExecutor.CallerRunsPolicy:主線程直接嘗試執行該任務;當線程池中可加入時,將任務添加到線程池中;該操作會重複執行,可以有效降低主線程將任務加入到線程池的速度;
  • ThreadPoolExecutor.DiscardOldestPolicy:直接拋棄舊的任務,即把線程池內最早加入隊列的線程拋棄;
  • ThreadPoolExecutor.DiscardPolicy:直接拋棄當前的任務;

再來說說java.util.concurrent.ScheduledThreadPoolExecutor ,此類是ThreadPoolExecutor的子類,所以以上我們描述的特性他都具備;除此之外,他還有一些自己特有的屬性和方法:

  • schedule(Runnable command, long delay, TimeUnit unit)
    該方法創建並執行在給定延遲後啓用的一次性任務;
  • scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
    該方法創建並執行一個在給定初始延遲後首次啓用的定期任務,後續任務具有指定的週期;也就是將在initialDelay後開始執行,然後在initialDelay+period 後執行,接着在initialDelay + 2 * period 後執行,依此類推。
  • scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
    該方法創建並執行一個在給定初始延遲後首次啓用的定期任務,隨後,在每一次執行終止和下一次執行開始之間都存在給定的延遲。

對於concurrent包在Spring中也進行了很多的封裝,對於一些可以採用FixedRate 或者FixedDelay 來進行調度的任務,非常的方便,相比較於Quartz的實現,在配置文件方面要減少很多,有興趣的同學可以參考Spring文檔中的《第23章 Spring中的定時調度和線程池》,重點關注兩個類:
org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean
org.springframework.scheduling.concurrent.ScheduledExecutorTask
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章