欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java線程數(shù)究竟設(shè)多少合理

 更新時間:2021年04月22日 15:51:13   作者:JiaJian  
這篇文章主要介紹了Java線程數(shù)究竟設(shè)多少合理,對線程感興趣的同學(xué),可以參考下

需求緣起

Web-Server通常有個配置,最大工作線程數(shù),后端服務(wù)一般也有個配置,工作線程池的線程數(shù)量,這個線程數(shù)的配置不同的業(yè)務(wù)架構(gòu)師有不同的經(jīng)驗值,有些業(yè)務(wù)設(shè)置為CPU核數(shù)的2倍,有些業(yè)務(wù)設(shè)置為CPU核數(shù)的8倍,有些業(yè)務(wù)設(shè)置為CPU核數(shù)的32倍。

“工作線程數(shù)”的設(shè)置依據(jù)是什么,到底設(shè)置為多少能夠最大化CPU性能,是本文要討論的問題。

一些共性認(rèn)知

在進(jìn)行進(jìn)一步深入討論之前,先以提問的方式就一些共性認(rèn)知達(dá)成一致。

1、提問:工作線程數(shù)是不是設(shè)置的越大越好?

回答:肯定不是的。

  • 一來服務(wù)器CPU核數(shù)有限,同時并發(fā)的線程數(shù)是有限的,1核CPU設(shè)置10000個工作線程沒有意義。
  • 線程切換是有開銷的,如果線程切換過于頻繁,反而會使性能降低。

2、提問:調(diào)用sleep()函數(shù)的時候,線程是否一直占用CPU?

回答:不占用,等待時會把CPU讓出來,給其他需要CPU資源的線程使用。

不止調(diào)用sleep()函數(shù),在進(jìn)行一些阻塞調(diào)用,例如網(wǎng)絡(luò)編程中的阻塞accept()【等待客戶端連接】和阻塞recv()【等待下游回包】也不占用CPU資源。

3、提問:如果CPU是單核,設(shè)置多線程有意義么,能提高并發(fā)性能么?

回答:即使是單核,使用多線程也是有意義的。

多線程編碼可以讓我們的服務(wù)/代碼更加清晰,有些IO線程收發(fā)包,有些Worker線程進(jìn)行任務(wù)處理,有些Timeout線程進(jìn)行超時檢測。

如果有一個任務(wù)一直占用CPU資源在進(jìn)行計算,那么此時增加線程并不能增加并發(fā),例如這樣的一個代碼:

while(1){ i++; }

該代碼一直不停的占用CPU資源進(jìn)行計算,會使CPU占用率達(dá)到100%。

通常來說,Worker線程一般不會一直占用CPU進(jìn)行計算,此時即使CPU是單核,增加Worker線程也能夠提高并發(fā),因為這個線程在休息的時候,其他的線程可以繼續(xù)工作。

常見服務(wù)線程模型

了解常見的服務(wù)線程模型,有助于理解服務(wù)并發(fā)的原理,一般來說互聯(lián)網(wǎng)常見的服務(wù)線程模型有如下兩種:

1. IO線程與工作線程通過隊列解耦類模型

如上圖,大部分Web-Server與服務(wù)框架都是使用這樣的一種 IO線程與Worker線程通過隊列解耦 類線程模型:

  • 有少數(shù)幾個IO線程監(jiān)聽上游發(fā)過來的請求,并進(jìn)行收發(fā)包(生產(chǎn)者)
  • 有一個或者多個任務(wù)隊列,作為IO線程與Worker線程異步解耦的數(shù)據(jù)傳輸通道(臨界資源)
  • 有多個工作線程執(zhí)行正真的任務(wù)(消費者)

這個線程模型應(yīng)用很廣,符合大部分場景,這個線程模型的特點是,工作線程內(nèi)部是同步阻塞執(zhí)行任務(wù)的(回想一下tomcat線程中是怎么執(zhí)行Java程序的,dubbo工作線程中是怎么執(zhí)行任務(wù)的),因此可以通過增加Worker線程數(shù)來增加并發(fā)能力,今天要討論的重點是:“該模型Worker線程數(shù)設(shè)置為多少能達(dá)到最大的并發(fā)”。

2. 純異步線程模型

任何地方都沒有阻塞,這種線程模型只需要設(shè)置很少的線程數(shù)就能夠做到很高的吞吐量,Lighttpd有一種單進(jìn)程單線程模式,并發(fā)處理能力很強(qiáng),就是使用的的這種模型。該模型的缺點是:

  • 如果使用單線程模式,難以利用多CPU多核的優(yōu)勢
  • 程序員更習(xí)慣寫同步代碼,callback的方式對代碼的可讀性有沖擊,對程序員的要求也更高
  • 框架更復(fù)雜,往往需要server端收發(fā)組件,server端隊列,client端收發(fā)組件,client端隊列,上下文管理組件,有限狀態(tài)機(jī)組件,超時管理組件的支持

however,這個模型不是今天討論的重點。

工作線程的工作模式

了解工作線程的工作模式,對量化分析線程數(shù)的設(shè)置非常有幫助:

上圖是一個典型的工作線程的處理過程,從開始處理start到結(jié)束處理end,該任務(wù)的處理共有7個步驟:

  1. 從工作隊列里拿出任務(wù),進(jìn)行一些本地初始化計算,例如http協(xié)議分析、參數(shù)解析、參數(shù)校驗等
  2. 訪問cache拿一些數(shù)據(jù)
  3. 拿到cache里的數(shù)據(jù)后,再進(jìn)行一些本地計算,這些計算和業(yè)務(wù)邏輯相關(guān)
  4. 通過RPC調(diào)用下游service再拿一些數(shù)據(jù),或者讓下游service去處理一些相關(guān)的任務(wù)
  5. RPC調(diào)用結(jié)束后,再進(jìn)行一些本地計算,怎么計算和業(yè)務(wù)邏輯相關(guān)
  6. 訪問DB進(jìn)行一些數(shù)據(jù)操作
  7. 操作完數(shù)據(jù)庫之后做一些收尾工作,同樣這些收尾工作也是本地計算,和業(yè)務(wù)邏輯相關(guān)

分析整個處理的時間軸,會發(fā)現(xiàn):

1)其中1,3,5,7步驟中【上圖中粉色時間軸】,線程進(jìn)行本地業(yè)務(wù)邏輯計算時需要占用CPU。
2)而2,4,6步驟中【上圖中橙色時間軸】,訪問cache、service、DB過程中線程處于一個等待結(jié)果的狀態(tài),不需要占用CPU。

進(jìn)一步的分解,這個“等待結(jié)果”的時間共分為三部分:

  1. 請求在網(wǎng)絡(luò)上傳輸?shù)较掠蔚腸ache、service、DB。
  2. 下游cache、service、DB進(jìn)行任務(wù)處理。
  3. cache、service、DB將報文在網(wǎng)絡(luò)上傳回工作線程。

量化分析并合理設(shè)置工作線程數(shù)

最后一起來回答工作線程數(shù)設(shè)置為多少合理的問題。

通過上面的分析,Worker線程在執(zhí)行的過程中,有一部計算時間需要占用CPU,另一部分等待時間不需要占用CPU,通過量化分析,例如打日志進(jìn)行統(tǒng)計,可以統(tǒng)計出整個Worker線程執(zhí)行過程中這兩部分時間的比例,例如:

  1. 時間軸1,3,5,7【上圖中粉色時間軸】的計算執(zhí)行時間是100ms 。
  2. 時間軸2,4,6【上圖中橙色時間軸】的等待時間也是100ms 。

得到的結(jié)果是,這個線程計算和等待的時間是1:1,即有50%的時間在計算(占用CPU),50%的時間在等待(不占用CPU):

  1. 假設(shè)此時是單核,則設(shè)置為2個工作線程就可以把CPU充分利用起來,讓CPU跑到100% 。
  2. 假設(shè)此時是N核,則設(shè)置為2N個工作線程就可以把CPU充分利用起來,讓CPU跑到N*100%。

結(jié)論

N核服務(wù)器,通過執(zhí)行業(yè)務(wù)的單線程分析出本地計算時間為x,等待時間為y,則工作線程數(shù)(線程池線程數(shù))設(shè)置為 N*(x+y)/x,能讓CPU的利用率最大化。

經(jīng)驗

一般來說,非CPU密集型的業(yè)務(wù)(加解密、壓縮解壓縮、搜索排序等業(yè)務(wù)是CPU密集型的業(yè)務(wù)),瓶頸都在后端數(shù)據(jù)庫,本地CPU計算的時間很少,所以設(shè)置幾十或者幾百個工作線程也都是可能的。

以上就是Java線程數(shù)究竟設(shè)多少合理的詳細(xì)內(nèi)容,更多關(guān)于Java線程數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java服務(wù)cpu100%的解決過程分享

    Java服務(wù)cpu100%的解決過程分享

    最近一個任務(wù)是優(yōu)化一個導(dǎo)出的功能,但是點擊功能時發(fā)現(xiàn),程序長時間無反應(yīng),過一段時間又有反應(yīng),通過查看服務(wù)的監(jiān)控發(fā)現(xiàn),服務(wù)存在cpu持續(xù)100%的情況,下面分享一下我的處理方案和過程,需要的朋友可以參考下
    2024-05-05
  • spring cloud實現(xiàn)前端跨域問題的解決方案

    spring cloud實現(xiàn)前端跨域問題的解決方案

    這篇文章主要介紹了 spring cloud實現(xiàn)前端跨域問題的解決方案,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Netty分布式Future與Promise執(zhí)行回調(diào)相關(guān)邏輯剖析

    Netty分布式Future與Promise執(zhí)行回調(diào)相關(guān)邏輯剖析

    這篇文章主要為大家介紹了Netty分布式Future與Promise執(zhí)行回調(diào)相關(guān)邏輯剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • java線程同步操作實例詳解

    java線程同步操作實例詳解

    這篇文章主要介紹了java線程同步操作,結(jié)合實例形式分析了Java線程同步與鎖機(jī)制相關(guān)原理、操作技巧與注意事項,需要的朋友可以參考下
    2018-09-09
  • 深入解析Java中的數(shù)據(jù)類型與變量

    深入解析Java中的數(shù)據(jù)類型與變量

    這篇文章主要介紹了深入解析Java中的數(shù)據(jù)類型與變量,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • Java圖片批量壓縮像素的實現(xiàn)方法

    Java圖片批量壓縮像素的實現(xiàn)方法

    我們開發(fā)中經(jīng)常會遇到原圖清晰度高,考慮到效率問題,我們不可能拿原圖進(jìn)行顯示,服務(wù)端一般都要對圖片進(jìn)行壓縮處理,然后發(fā)送給客戶端顯示,這篇文章主要給大家介紹了關(guān)于Java圖片批量壓縮像素的實現(xiàn)方法,需要的朋友可以參考下
    2021-12-12
  • 深入解析Java反射之基礎(chǔ)篇

    深入解析Java反射之基礎(chǔ)篇

    JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法,這篇文章主要給大家介紹了關(guān)于Java反射之基礎(chǔ)篇的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • Java文檔注釋超詳細(xì)講解

    Java文檔注釋超詳細(xì)講解

    這篇文章主要給大家介紹了關(guān)于Java文檔注釋的相關(guān)資料,文檔注釋主要是用來生成java開發(fā)文檔javadoc的,生成的開發(fā)文檔和Java本身的API幫助文檔是一樣的,需要的朋友可以參考下
    2023-10-10
  • Java 從互聯(lián)網(wǎng)上爬郵箱代碼示例

    Java 從互聯(lián)網(wǎng)上爬郵箱代碼示例

    這篇文章介紹了Java 從互聯(lián)網(wǎng)上爬郵箱的有關(guān)內(nèi)容,主要是一個代碼示例,小編覺得挺不錯的,這里給大家分享下,需要的朋友可以了解。
    2017-10-10
  • SpringBoot整合JPA方法及配置解析

    SpringBoot整合JPA方法及配置解析

    這篇文章主要介紹了SpringBoot整合JPA方法及配置過程,JPA是Java Persistence API的簡稱,中文名Java持久層API,感興趣想要詳細(xì)了解可以參考下文
    2023-05-05

最新評論