什么是線程池
線程池是一種多線程處理形式,處理過程中將任務添加到隊列,然后在創建線程后自動啟動這些任務。線程池線程都是后台線程。每個線程都使用默認的堆棧大小,以默認的優先級運行,並處於多線程單元中。如果某個線程在托管代碼中空閑(如正在等待某個事件),則線程池將插入另一個輔助線程來使所有處理器保持繁忙。如果所有線程池線程都始終保持繁忙,但隊列中包含掛起的工作,則線程池將在一段時間后創建另一個輔助線程但線程的數目永遠不會超過最大值。超過最大值的線程可以排隊,但他們要等到其他線程完成后才啟動。【來自於百度百科】
為什么需要用到線程池
通過上面線程池的簡介,我們其實可以發現,普通的創建一個線程都是及創及用,並且沒有上線,我想創建1000個線程或者創建10000個線程都可以,但是這樣創建線程的方式有一個問題,那就是忽略了執行環境的性能,比如我們平時一個64位4核的服務器,他建議的線程數可以由公示算出來
線程池大小 = (物理CPU數量 x CPU核數) + 1
如何獲取linux服務器邏輯CPU個數可以使用下面這個命令
邏輯CPU個數,使用命令: cat /proc/cpuinfo | grep 'processor' | wc -l
物理CPU個數,使用命令: cat /proc/cpuinfo | grep 'physical id' | sort | uniq | wc -l
這里例如我這里4核的服務器,邏輯CUP個數是4個,那么他的建議線程池大小為17個。相對於10000個線程是遠遠不夠的,如果我們創建普通的線程遠遠大於17個線程,那么就會給服務器的CPU線程造成很大的開銷,甚至會讓多線程執行變得還沒有單線程執行的快。
那么線程池的作用就顯示出來了,他就是為了去控制線程執行的上線,同時也會給線程保持活躍性,比如10000個線程在線程中執行,他會先執行17個線程,聲線的9983個線程就會在線程的隊列中等待,等到之前17個線程中有執行完畢的線程讓出了位置,這是后面排隊的線程才可以繼續補上執行,這樣就最大限度的保證了cup執行線程最大的性能。減少了CUP很多的調度開銷。當當前沒有17個線程執行的時候,線程池也會創建輔助線程放在線程池中,來保持17個線程的活躍性,這讓下次來了新的線程,線程池就減少了創建線程的開銷,直接開箱即用。這就是為什么需要使用線程池的目的。
使用線程的好處
- 線程池可以解決線程生命周期的系統開銷問題,同時還可以加快響應速度。因為線程池中的線程是可以復用的,我們只用少量的線程去執行大量的任務,這就大大減小了線程生命周期的開銷。而且線程通常不是等接到任務后再臨時創建,而是已經創建好時刻准備執行任務,這樣就消除了線程創建所帶來的延遲,提升了響應速度,增強了用戶體驗。
- 線程池可以統籌內存和 CPU 的使用,避免資源使用不當。線程池會根據配置和任務數量靈活地控制線程數量,不夠的時候就創建,太多的時候就回收,避免線程過多導致內存溢出,或線程太少導致 CPU 資源浪費,達到了一個完美的平衡。
- 線程池可以統一管理資源。比如線程池可以統一管理任務隊列和線程,可以統一開始或結束任務,比單個線程逐一處理任務要更方便、更易於管理,同時也有利於數據統計,比如我們可以很方便地統計出已經執行過的任務的數量。