面試題:合適的線程數量是多少?CPU 核心數和線程數的關系?


合適的線程數量是多少?CPU 核心數和線程數的關系?

CPU 密集型任務
首先,我們來看 CPU 密集型任務,比如加密、解密、壓縮、計算等一系列需要大量耗費 CPU 資源的任務。對於這樣的任務最佳的線程數為 CPU 核心數的 1~2 倍,如果設置過多的線程數,實際上並不會起到很好的效果。此時假設我們設置的線程數量是 CPU 核心數的 2 倍以上,因為計算任務非常重,會占用大量的 CPU 資源,所以這時 CPU 的每個核心工作基本都是滿負荷的,而我們又設置了過多的線程,每個線程都想去利用 CPU 資源來執行自己的任務,這就會造成不必要的上下文切換,此時線程數的增多並沒有讓性能提升,反而由於線程數量過多會導致性能下降。

針對這種情況,我們最好還要同時考慮在同一台機器上還有哪些其他會占用過多 CPU 資源的程序在運行,然后對資源使用做整體的平衡。

耗時 IO 型任務
第二種任務是耗時 IO 型,比如數據庫、文件的讀寫,網絡通信等任務,這種任務的特點是並不會特別消耗 CPU 資源,但是 IO 操作很耗時,總體會占用比較多的時間。對於這種任務最大線程數一般會大於 CPU 核心數很多倍,因為 IO 讀寫速度相比於 CPU 的速度而言是比較慢的,如果我們設置過少的線程數,就可能導致 CPU 資源的浪費。而如果我們設置更多的線程數,那么當一部分線程正在等待 IO 的時候,它們此時並不需要 CPU 來計算,那么另外的線程便可以利用 CPU 去執行其他的任務,互不影響,這樣的話在任務隊列中等待的任務就會減少,可以更好地利用資源。

《Java並發編程實戰》的作者 Brain Goetz 推薦的計算方法:

線程數 = CPU 核心數 *(1+平均等待時間/平均工作時間)

通過這個公式,我們可以計算出一個合理的線程數量,如果任務的平均等待時間長,線程數就隨之增加,而如果平均工作時間長,也就是對於我們上面的 CPU 密集型任務,線程數就隨之減少。

太少的線程數會使得程序整體性能降低,而過多的線程也會消耗內存等其他資源,所以如果想要更准確的話,可以進行壓測,監控 JVM 的線程情況以及 CPU 的負載情況,根據實際情況衡量應該創建的線程數,合理並充分利用資源。

結論:

  • 線程的平均工作時間所占比例越高,就需要越少的線程;

  • 線程的平均等待時間所占比例越高,就需要越多的線程;

  • 針對不同的程序,進行對應的實際測試就可以得到最合適的選擇。


免責聲明!

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



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