石家莊做網(wǎng)站建設(shè)公司外鏈查詢
目錄
1、機器配置:
2、核心線程數(shù)
3、最大線程數(shù)多少合適?
4、理論基礎(chǔ)
5、測試驗證
一個線程跑滿一個核心的利用率
6個線程
12 個線程:所有核的cpu利用率都跑滿
有io操作
6、計算公式
7、決定最大線程數(shù)的流程:
1、機器配置:
????????4核8g內(nèi)存
2、核心線程數(shù)
????????就是cpu核數(shù)就行
3、最大線程數(shù)多少合適?
????線程池設(shè)置多大,并沒有固定答案, 需要結(jié)合實際情況不斷的測試才能得出最準(zhǔn)確的數(shù)據(jù).
4、理論基礎(chǔ)
- 一個 CPU 核心,某一時刻只能執(zhí)行一個線程的指令
- 一個極端的線程,就可以把單個核心的利用率跑滿,多核心 CPU 最多同時執(zhí)行等于核心數(shù)的 “極端” 線程數(shù)
- 如果每個線程都這么 “極端”,且同時執(zhí)行的線程數(shù)超過核心數(shù),會導(dǎo)致不必要的切換,造成負(fù)載過高,只會讓執(zhí)行更慢
- I/O 等暫停類操作時,CPU 處于空閑狀態(tài),操作系統(tǒng)調(diào)度 CPU 執(zhí)行其他線程,可以提高 CPU 利用率,同時執(zhí)行更多的線程
- I/O 事件的頻率頻率越高,或者等待 / 暫停時間越長,CPU 的空閑時間也就更長,利用率越低,操作系統(tǒng)可以調(diào)度 CPU 執(zhí)行更多的線程
5、測試驗證(測試機器12cpu)
一個線程跑滿一個核心的利用率
public class CPUUtilizationTest {public static void main(String[] args) {//死循環(huán),什么都不做while (true){}}
}
從圖上可以看到,我的 3 號核心利用率已經(jīng)被跑滿了
6個線程
public class CPUUtilizationTest {public static void main(String[] args) {for (int j = 0; j < 6; j++) {new Thread(new Runnable() {@Overridepublic void run() {while (true){}}}).start();}}
}
此時再看 CPU 利用率,1/2/5/7/9/11 幾個核心的利用率已經(jīng)被跑滿
12 個線程:所有核的cpu利用率都跑滿
有io操作
上面的例子中,程序不停的循環(huán)什么都不做,CPU 要不停的執(zhí)行指令,幾乎沒有啥空閑的時間。如果插入一段 I/O 操作呢,I/O 操作期間 CPU 是空閑狀態(tài),CPU 的利用率會怎么樣呢?先看看單線程下的結(jié)果:
public class CPUUtilizationTest {public static void main(String[] args) throws InterruptedException {for (int n = 0; n < 1; n++) {new Thread(new Runnable() {@Overridepublic void run() {while (true){//每次空循環(huán) 1億 次后,sleep 50ms,模擬 I/O等待、切換for (int i = 0; i < 100_000_000l; i++) { }try {Thread.sleep(50);}catch (InterruptedException e) {e.printStackTrace();}}}}).start();}}
}
只有9 號核心的利用率較高,大但也才 50%,和前面沒有 sleep 的 100% 相比,已經(jīng)低了一半了?,F(xiàn)在把線程數(shù)調(diào)整到 12 個看看:
單個核心的利用率 60 左右
6、計算公式
7、決定最大線程數(shù)的流程:
- 分析當(dāng)前主機上,有沒有其他進程干擾
- 分析當(dāng)前 JVM 進程上,有沒有其他運行中或可能運行的線程
- 設(shè)定目標(biāo)
- 目標(biāo) CPU 利用率 - 我最高能容忍我的 CPU 飆到多少?
- 目標(biāo) GC 頻率 / 暫停時間 - 多線程執(zhí)行后,GC 頻率會增高,最大能容忍到什么頻率,每次暫停時間多少
- 不斷的增加 / 減少線程數(shù)來測試,按最高的要求去測試,最終獲得一個 “滿足要求” 的線程數(shù)