多個場景共用一個大的線程池還是每個任務單獨使用線程池


1.首先,項目中如果有多個場景需要使用線程池,那么最好的方式是:每一個業務場景使用獨立的線程池。不要讓所有的場景共用一個線程池。

分析:

1)獨立的線城池之間互相不影響彼此的任務作業,更有利於保證本任務的獨立性和完整性,更符合低耦合的設計思想

2)如果所有的場景共用一個線程池,可能會出現如下問題,舉例:

比如有任務A、任務B、任務C   這三個任務場景共用一個線程池,配置如下

threadPool:
  corePoolSize: 20
  maximumPoolSize : 2000
  workQueue : 1000
  keepAliveSeconds: 300
  • 第1個參數 :corePoolSize 表示常駐核心線程數。如果等於0,則任務執行完成后,沒有任何請求進入時銷毀線程池的線程;如果大於0,即使本地任務執行完畢,核心線程也不會被銷毀。這個值的設置非常關鍵,設置過大會浪費資源,設置的過小會導致線程頻繁地創建或銷毀。
  • 第2個參數:maximumPoolSize 表示線程池能夠容納同時執行的最大線程數。從上方的示例代碼中第一處來看,必須大於或等於1。如果待執行的線程數大於此值,需要借助第5個參數的幫助。緩存在隊列中。如果maximumPoolSize 與corePoolSize 相等,即是固定大小線程池。
  • 第3個參數: workQueue 表示緩存隊列。如果線程池里的線程數大於corePoolSize ,就會放到緩存隊列,緩存隊列滿了會創建新線程到maximumPoolsize;直到當請求的線程數大於maximumPoolSize時,會執行設定的策略,默認是拒絕創建策略。(注意:當線程池里的線程數大於corePoolSize且小於maximumPoolSize時,這時候再有請求的線程就會放到緩存隊列,注意只是放到緩存隊列但是不創建新的線程,直到請求的線程存滿緩存隊列時,才會開始創建新的線程,直到maxmunPoolSize就會拒絕創建或者執行提前設定的策略。
  • 第4個參數:  keepAliveSeconds
    表示線程池中的線程空閑時間,當空閑時間達到keepAliveSeconds值時,線程被銷毀,直到剩下corePoolSize 個線程為止,避免浪費內存和句柄資源。在默認情況下,當線程池的線程大於corePoolSize 時,keepAliveSeconds才會起作用。但是ThreadPoolExecutor的allowCoreThreadTimeOut 變量設置為ture時,核心線程超時后也會被回收。

 當任務A請求量劇烈增加的時候就會導致任務B和任務C,沒有可用的線程  可能出現遲遲獲取不到資源的情況。比如任務A同時有3000個線程請求,此時就可能會導致  任務B和任務C分配不到資源或者分配到很少的線程資源。

所以為了避免這種情況的產生,最好的方式是建立獨立的線程池。

這樣不管任務A的線程是堵塞還是其他原因,都不會影響任務B和任務C,同理任務B、任務C也一樣不會影響其他場景任務的執行。

2.注:

1.JDK自帶的類使用了很多的線程池.
2.很多開源框架使用了大量的線程池.
3.自己的應用也會創建多個線程池.
4.不要在意什么CPU密集還是IO密集(這是一種人雲亦雲的說法,至少java語言來說不要考慮什么IO還是CPU).
5.多少個線程池,每個線程池提供多少線程,必須經過詳細的測試,不能人雲亦雲,不能參考別人.
不同的業務,不同的場景,線程池的個數,線程的數量都是不一樣的.

一台服務器硬件資源是固定的,比如20核心40線程的CPU,能部署一個應用,就盡量部署一個,不要什么都部署.

經過測試你會發現:

有時候線程創建多了會消耗大量的內存,關鍵是無法提升性能.
當你創建1個線程,5線程,10線程時,處理數據的性能差不多,那就不應該創建多個.
所以,線程池相關的問題,需要經過長時間的測試,不斷的測試最終提供一套符合目前需求的參數.


免責聲明!

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



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