線程池的七個參數及JAVA線程池種類


一 線程池的七個參數

public ThreadPoolExecutor(int corePoolSize,

                              int maximumPoolSize,

                              long keepAliveTime,

                              TimeUnit unit,

                              BlockingQueue<Runnable> workQueue,

                              ThreadFactory threadFactory,

                              RejectedExecutionHandler handler) 

 線程池一共有七個構造函數,看看他的作用吧:

1、int corePoolSize  線程池核心線程大小即線程創建的最小線程數

  線程池中會維護一個最小線程數量,即使這些線程處於空閑狀態,也不會被銷毀,除非設置了allowCoreThreadTimeOut。這里的最小線程數就是corePoolSize

 

2、int maximumPoolSize 線程池的最大線程數量

  一個任務被提交到線程池后,首先會緩存到工作隊列中,如果工作隊列滿了,則會創建一個新線程,然后從工作隊列中去除一個任務交由新線程來處理,而將剛提交的任務放入到工作隊列中線程池不會無限制的去創建新線程,會有一個最大線程數量的限制,這個數量是有maximumPoolSize 來控制

 

3、long keepAliveTime 空閑線程存活時間

  一個線程處於空閑狀態,並且當前的線程數量大於corePoolSize,那么在指定時間內,這個空閑線程就會被銷毀,這個指定時間是由keepAliveTime來設定

 

4、TimeUnit unit 空閑線程存活時間單位

  是keepAliveTime 的計量單位

5、BlockingQueue<Runnable> workQueue  工作隊列

  新任務被提交后,會先進入到此工作隊列中,任務調度時再從隊列中取出任務,jdk提供了四種工作隊列,可以了解一下:

  1)  ArrayBlockingQueue 

  基於數組的有界阻塞隊列, 於數組的有界阻塞隊列,按FIFO排序。新任務進來后,會放到該隊列的隊尾,有界的數組可以防止資源耗盡問題。當線程池中線程數量達到corePoolSize后,再有新任務進來,則會將任務放入該隊列的隊尾,等待被調度。如果隊列已經是滿的,則創建一個新線程,如果線程數量已經達到maxPoolSize,則會執行拒絕策略。

  2) LinkedBlockingQuene

  基於鏈表的無界阻塞隊列(其實最大容量為Interger.MAX),按照FIFO排序。由於該隊列的近似無界性,當線程池中線程數量達到corePoolSize后,再有新任務進來,會一直存入該隊列,而不會去創建新線程直到maxPoolSize,因此使用該工作隊列時,參數maxPoolSize其實是不起作用的。
  3) SynchronousQuene
   一個不緩存任務的阻塞隊列,生產者放入一個任務必須等到消費者取出這個任務。也就是說新任務進來時,不會緩存,而是直接被調度執行該任務,如果沒有可用線程,則創建新線程,如果線程數量達到maxPoolSize,則執行拒絕策略。
  4) PriorityBlockingQueue
   具有優先級的無界阻塞隊列,優先級通過參數Comparator實現。

6、ThreadFactory threadFactory 線程工廠

   創建一個新線程時使用的工廠,可以用來設定線程名、是否為daemon線程等等

7、RejectedExecutionHandler handler 拒絕策略

   當工作隊列中的任務已到達最大限制,並且線程池中的線程數量也達到最大限制,這時如果有新任務提交進來,該如何處理呢。這里的拒絕策略,就是解決這個問題的,jdk中提供了4中拒絕策略:

   1)CallerRunsPolicy

   該策略下,在調用者線程中直接執行被拒絕任務的run方法,除非線程池已經shutdown,則直接拋棄任務。

   2)AbortPolicy
   該策略下,直接丟棄任務,並拋出RejectedExecutionException異常。
   3)DiscardPolicy
   該策略下,直接丟棄任務,什么都不做。
   4)DiscardOldestPolicy
   該策略下,拋棄進入隊列最早的那個任務,然后嘗試把這次拒絕的任務放入隊列
 
 
二 、線程池種類
 
1、newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。 線程池為無限大,當執行第二個任務時第一個任務已經完成,會復用執行第一個任務的線程,而不用每次新建線程。 可能導致內存溢出,一般使用newFixedThreadPool代替 
 
2、newFixedThreadPool 創建一個定長線程池,可控制線程最大並發數,超出的線程會在隊列中等待。
 
3、newScheduledThreadPool 創建一個定長線程池,支持定時及周期性任務執行。
 
4、newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。
 
5、newSingleThreadScheduledExecutor  創建只有一條線程的線程池,他可以在指定延遲后執行線程任務 
 
 6、newWorkStealingPool(這個是在jdk1.8出來的)會更加所需的並行層次來動態創建和關閉線程。它同樣會試圖減少任務隊列的大小,所以比較適於高負載的環境。同樣也比較適用於當執行的任務會創建更多任務,如遞歸任務。適合使用在很耗時的操作,但是newWorkStealingPool不是ThreadPoolExecutor的擴展,它是新的線程池類ForkJoinPool的擴展,但是都是在統一的一個Executors類中實現,由於能夠合理的使用CPU進行對任務操作(並行操作),所以適合使用在很耗時的任務中
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM