最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java線程數究竟設多少合理

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

需求緣起

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

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

一些共性認知

在進行進一步深入討論之前,先以提問的方式就一些共性認知達成一致。

1、提問:工作線程數是不是設置的越大越好?

回答:肯定不是的。

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

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

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

不止調用sleep()函數,在進行一些阻塞調用,例如網絡編程中的阻塞accept()【等待客戶端連接】和阻塞recv()【等待下游回包】也不占用CPU資源。

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

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

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

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

while(1){ i++; }

該代碼一直不停的占用CPU資源進行計算,會使CPU占用率達到100%。

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

常見服務線程模型

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

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

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

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

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

2. 純異步線程模型

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

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

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

工作線程的工作模式

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

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

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

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

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

進一步的分解,這個“等待結果”的時間共分為三部分:

  1. 請求在網絡上傳輸到下游的cache、service、DB。
  2. 下游cache、service、DB進行任務處理。
  3. cache、service、DB將報文在網絡上傳回工作線程。

量化分析并合理設置工作線程數

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

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

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

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

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

結論

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

經驗

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

以上就是Java線程數究竟設多少合理的詳細內容,更多關于Java線程數的資料請關注腳本之家其它相關文章!

相關文章

  • 解決mybatis竟然報Invalid value for getInt()的問題

    解決mybatis竟然報Invalid value for getInt()的問題

    使用mybatis遇到一個非常奇葩的問題,總是報Invalid value for getInt()的問題,怎么解決呢?下面小編通過場景分析給大家代來了mybatis報Invalid value for getInt()的解決方法,感興趣的朋友參考下吧
    2021-10-10
  • SLF4J報錯解決:No SLF4J providers were found的問題

    SLF4J報錯解決:No SLF4J providers were found的

    這篇文章主要介紹了SLF4J報錯解決:No SLF4J providers were found的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • 如何解決java.lang.IllegalStateException: Target host is null的問題

    如何解決java.lang.IllegalStateException: Target host&n

    文章描述了通過MocoRunner模擬接口,并使用properties文件和ResourceBundle讀取配置文件進行get請求的過程,在執(zhí)行過程中遇到了目標主機為空的錯誤,通過檢查和修正url拼接問題解決了該錯誤
    2024-12-12
  • springboot集成@DS注解實現數據源切換的方法示例

    springboot集成@DS注解實現數據源切換的方法示例

    本文主要介紹了springboot集成@DS注解實現數據源切換的方法示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • springboot啟動流程過程

    springboot啟動流程過程

    Spring Boot 簡化了 Spring 框架的使用,通過創(chuàng)建 `SpringApplication` 對象,判斷應用類型并設置初始化器和監(jiān)聽器,在 `run` 方法中,讀取配置并加載到 `Environment` 中,通過 Spring 事件機制和 `EnvironmentPostProcessor` 處理配置
    2025-02-02
  • springboot動態(tài)加載Echarts柱狀圖

    springboot動態(tài)加載Echarts柱狀圖

    這篇文章主要為大家詳細介紹了springboot動態(tài)加載Echarts柱狀圖,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • java性能分析jconsole詳解

    java性能分析jconsole詳解

    這篇文章主要介紹了java性能分析jconsole詳解,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • ScheduledThreadPoolExecutor巨坑解決

    ScheduledThreadPoolExecutor巨坑解決

    這篇文章主要為大家介紹了使用ScheduledThreadPoolExecutor遇到的巨坑解決示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • SpringBoot實現動態(tài)加載外部Jar流程詳解

    SpringBoot實現動態(tài)加載外部Jar流程詳解

    這篇文章主要介紹了SpringBoot動態(tài)加載外部Jar的流程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2023-05-05
  • Java抽象類、繼承及多態(tài)和適配器的實現代碼

    Java抽象類、繼承及多態(tài)和適配器的實現代碼

    這篇文章主要介紹了Java抽象類、繼承及多態(tài)和適配器的實現,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-06-06

最新評論

沁阳市| 桦川县| 健康| 乌拉特后旗| 南木林县| 马边| 定兴县| 阿城市| 临城县| 东阿县| 安福县| 濮阳县| 兰西县| 盱眙县| 兰考县| 乐安县| 遂昌县| 贺州市| 两当县| 隆安县| 东乌珠穆沁旗| 藁城市| 麻阳| 屏山县| 肥城市| 双峰县| 卓尼县| 包头市| 拜泉县| 崇州市| 石屏县| 苍山县| 寻甸| 宁安市| 双流县| 迁西县| 买车| 肇州县| 祁门县| 汕头市| 达尔|