設置線程數的核心點
- 壓測!壓測!壓測!
- 本文的思路為預估的方式,適合初始值。實際對性能要求比較高的場景,壓測是最佳的方式!
- 最核心的思路:壓榨(更好的利用)CPU的性能。
先考慮為什么要設置不同的線程數
- 我們調整線程池中的線程數量的最主要的目的是為了充分並合理地使用 CPU 和內存等資源,從而最大限度地提高程序的性能。
- 在實際工作中,我們需要根據任務類型的不同選擇對應的策略。
CPU密集型任務
- CPU密集型任務也叫計算密集型任務。
- 比如加密、解密、壓縮、計算等一系列需要大量耗費 CPU 資源的任務。
- CPU密集型任務最佳的線程數為 CPU 核心數的 1~2 倍。
- 如果設置過多的線程數,實際上並不會起到很好的效果。
- 假設我們設置的線程數量是 CPU 核心數的 2 倍以上,因為計算任務非常重,會占用大量的 CPU 資源,所以這時 CPU 的每個核心工作基本都是滿負荷的。
- 我們又設置了過多的線程,每個線程都想去利用 CPU 資源來執行自己的任務,這就會造成不必要的上下文切換,此時線程數的增多並沒有讓性能提升,反而由於線程數量過多會導致性能下降。
IO密集型任務
- 比如數據庫、文件的讀寫,網絡通信等任務。
- 並不會特別消耗 CPU 資源,但是 IO 操作很耗時,總體會占用比較多的時間。
- IO密集型任務最大線程數一般會大於 CPU 核心數很多倍,因為 IO 讀寫速度相比於 CPU 的速度而言是比較慢的,如果我們設置過少的線程數,就可能導致 CPU 資源的浪費。
- 如果我們設置更多的線程數,那么當一部分線程正在等待 IO 的時候,它們此時並不需要 CPU 來計算,那么另外的線程便可以利用 CPU 去執行其他的任務,互不影響,這樣的話在工作隊列中等待的任務就會減少,可以更好地利用資源。
- 《Java並發編程實戰》的作者 Brain Goetz 推薦的計算方法:線程數 = CPU 核心數 *(1+平均等待時間/平均工作時間)。通過這個公式,我們可以計算出一個合理的線程數量,如果任務的平均等待時間長,線程數就隨之增加,而如果平均工作時間長,也就是對於我們上面的 CPU 密集型任務,線程數就隨之減少。
設置線程數的核心
- 太少的線程數會使得程序整體性能降低,而過多的線程也會消耗內存等其他資源,所以如果想要更准確的話,可以進行壓測,監控 JVM 的線程情況以及 CPU 的負載情況,根據實際情況衡量應該創建的線程數,合理並充分利用資源。
結束語
- 獲取更多本文的前置知識文章,以及新的有價值的文章,讓我們一起成為架構師!
- 關注公眾號,可以讓你對MySQL有非常深入的了解
- 關注公眾號,每天持續高效的了解並發編程!
- 關注公眾號,后續持續高效的了解spring源碼!
- 這個公眾號,無廣告!!!每日更新!!!