線程池的種類,區別和使用場景

newCachedThreadPool算法

  • 底層:返回ThreadPoolExecutor實例,corePoolSize0maximumPoolSizeInteger.MAX_VALUEkeepAliveTime60LunitTimeUnit.SECONDSworkQueueSynchronousQueue(同步隊列)
  • 通俗:當有新任務到來,則插入到SynchronousQueue中,因爲SynchronousQueue是同步隊列,所以會在池中尋找可用線程來執行,如有能夠線程則執行,若沒有可用線程則建立一個線程來執行該任務;若池中線程空閒時間超過指定大小,則該線程會被銷燬。
  • 適用:執行不少短時間異步的小程序或者負載較輕的服務器

newFixedThreadPool小程序

  • 底層:返回ThreadPoolExecutor實例,接收參數爲所設定線程數量nThreadcorePoolSizenThreadmaximumPoolSizenThreadkeepAliveTime0L(不限時)unit爲:TimeUnit.MILLISECONDSWorkQueue爲:new LinkedBlockingQueue<Runnable>() 無解阻塞隊列
  • 通俗:建立可容納固定數量線程的池子,每隔線程的存活時間是無限的,當池子滿了就不在添加線程了;若是池中的全部線程均在繁忙狀態,對於新任務會進入阻塞隊列中(無界的阻塞隊列)
  • 適用:執行長期的任務,性能好不少

newSingleThreadExecutor:服務器

  • 底層:FinalizableDelegatedExecutorService包裝的ThreadPoolExecutor實例,corePoolSize1maximumPoolSize1keepAliveTime0Lunit爲:TimeUnit.MILLISECONDSworkQueue爲:new LinkedBlockingQueue<Runnable>() 無解阻塞隊列
  • 通俗:建立只有一個線程的線程池,且線程的存活時間是無限的;當該線程正繁忙時,對於新任務會進入阻塞隊列中(無界的阻塞隊列)
  • 適用:一個任務一個任務執行的場景

NewScheduledThreadPool:異步

  • 底層:建立ScheduledThreadPoolExecutor實例,corePoolSize爲傳遞來的參數,maximumPoolSizeInteger.MAX_VALUEkeepAliveTime0unit爲:TimeUnit.NANOSECONDSworkQueue爲:new DelayedWorkQueue() 一個按超時時間升序排序的隊列
  • 通俗:建立一個固定大小的線程池,線程池內線程存活時間無限制,線程池能夠支持定時及週期性任務執行,若是全部線程均處於繁忙狀態,對於新任務會進入DelayedWorkQueue隊列中,這是一種按照超時時間排序的隊列結構
  • 適用:週期性執行任務的場景

線程池任務執行流程:性能

  1. 當線程池小於corePoolSize時,新提交任務將建立一個新線程執行任務,即便此時線程池中存在空閒線程。
  2. 當線程池達到corePoolSize時,新提交任務將被放入workQueue中,等待線程池中任務調度執行
  3. workQueue已滿,且maximumPoolSize>corePoolSize時,新提交任務會建立新線程執行任務
  4. 當提交任務數超過maximumPoolSize時,新提交任務由RejectedExecutionHandler處理
  5. 當線程池中超過corePoolSize線程,空閒時間達到keepAliveTime時,關閉空閒線程
  6. 當設置allowCoreThreadTimeOut(true)時,線程池中corePoolSize線程空閒時間達到keepAliveTime也將關閉

備註:spa

通常若是線程池任務隊列採用LinkedBlockingQueue隊列的話,那麼不會拒絕任何任務(由於隊列大小沒有限制),這種狀況下,ThreadPoolExecutor最多僅會按照最小線程數來建立線程,也就是說線程池大小被忽略了。線程

若是線程池任務隊列採用ArrayBlockingQueue隊列的話,那麼ThreadPoolExecutor將會採起一個很是負責的算法,好比假定線程池的最小線程數爲4,最大爲8所用的ArrayBlockingQueue最大爲10。隨着任務到達並被放到隊列中,線程池中最多運行4個線程(即最小線程數)。即便隊列徹底填滿,也就是說有10個處於等待狀態的任務,ThreadPoolExecutor也只會利用4個線程。若是隊列已滿,而又有新任務進來,此時纔會啓動一個新線程,這裏不會由於隊列已滿而拒接該任務,相反會啓動一個新線程。新線程會運行隊列中的第一個任務,爲新來的任務騰出空間。排序

這個算法背後的理念是:該池大部分時間僅使用核心線程(4個),即便有適量的任務在隊列中等待運行。這時線程池就能夠用做節流閥。若是擠壓的請求變得很是多,這時該池就會嘗試運行更多的線程來清理;這時第二個節流閥—最大線程數就起做用了。隊列

相關文章
相關標籤/搜索