自定義線程池,如何最佳創建線程池


java有預置線程池:newSingleThreadExecutor,newFixedThreadPool,newCacheedThreadPool,newScheduledThreadPool,newWorkStealingPool。如果不適合,還可以使用ThreadPoolExecutor創建自定義線程池。主要構造方法:

 1 public ThreadPoolExecutor(int corePoolSize,
 2                           int maximumPoolSize,
 3                           long keepAliveTime,
 4                           TimeUnit unit,
 5                           BlockingQueue<Runnable> workQueue)
 6 
 7 public ThreadPoolExecutor(int corePoolSize,
 8                           int maximumPoolSize,
 9                           long keepAliveTime,
10                           TimeUnit unit,
11                           BlockingQueue<Runnable> workQueue,
12                           ThreadFactory threadFactory,
13                           RejectedExecutionHandler handler)

我們接下來介紹參數,其中線程池大小與前四個參數有關。

  • corePoolSize: 核心線程數。
    • 剛創建線程池,沒有,即不會預先創建。當任務到來,且當前線程沒有超過corePoolSize,就會創建一個新線程執行該任務,即使其他線程是空閑。
    • 不會因為空閑而被釋放,keepAliveTime不適用。
  • maximumPoolSize:最大線程數。如上面情況,如果當前線程超過corePoolSize,先嘗試排隊,如果隊列滿了或者其他情況不能入隊,那么它不會排隊,而是檢查線程數是否達到maximumPoolSize,如果沒有,就創建線程,直到線程數達到maximumPoolSize。
  • keepAliveTime:空閑線程存活時間。當線程池的線程數大於corePoolSize,額外空閑線程的存活時間。如果到了時間,還沒有新任務,就會釋放線程。值為0,表示線程不會超時釋放。
  • unit
  • BlockingQueue:阻塞隊列。可以使用LinkedBlockingQueue(默認無界)、ArrayBlockingQueue、PriorityBlockingQueue(無界)、SynchronousQueue(沒實際存儲空間)。使用無界隊列,需要注意,線程數最多達到corePoolSize,新任務來只能排隊,maximumPoolSize沒意義。SynchronousQueue只有正好有空閑線程,才會入隊成功,否則總是創建新線程,直到達到maximumPoolSize。
  • handler:任務拒絕策略。有界隊列,線程數達到maximumPoolSize,隊列滿了,觸發任務拒絕策略。四種處理方式:AbortPolicy(默認,拋出異常),DiscardPolicy(忽略新任務,不拋異常),DiscardOldestPolicy(扔掉等待時間最長,自己排隊),CallerRunsPolicy(任務提交者線程執行任務)

最佳自定義創建線程池,隊列有界,maximumPoolSize有限,使用任務拒絕策略。如果隊列無界,服務不了的任務總是會排隊,消耗內存,甚至引發內存不足異常。如果隊列有界但maximumPoolSize無線,可能會創建過多線程,占內存和CPU。

 


免責聲明!

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



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