使用線程池做并發程式設計中,遇到個問題就是:線程池大小該設定多少。線程池并非越大越好,設定大了,在cpu資源有限的情況下,部分線程擷取資源的時間會大幅度增加,進而完成時間也會增加的。
開始使用newFixedThreadPool建立線程池進行并發網絡請求時,我設定線程數為5(電腦為雙核),執行的時候發現結果出的很慢,通過Wireshark抓包,發現最早進入線程池的兩個任務,真正執行卻很晚,而其餘線程中任務都跑了好幾次了。
我這是網絡請求,總共執行了20個任務,就通過src port進行對線程進行标記統計了下:
53147 53148 53145 53144 53146
1 6 7 5 1
可以看出53147與53146隻執行了一次任務,是以這兩個端口對應的線程就是一直擷取不到資源,開始執行時間很晚的那部分;
在網上查了其他資料,有文章指出:
如果是CPU密集型應用,則線程池大小設定為N+1
如果是IO密集型應用,則線程池大小設定為2N+1
上面已經是2N+1了,于是改為N+1,設定線程池大小為3,開始執行到出結果平均是原本時間的一半,從執行分布看也是很均勻:
53301 53500 53502
7 6 7
當然這裡任務數不多,任務數多的話還需根據情況測試調整線程池大小了。