成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java線程:創建多少線程才是合適的?

開發 前端
很多人都知道線程數不是越多越好,但是設置多少是合適的,卻又拿不定主意。其實只要把握住一條原則就可以了,這條原則就是將硬件的性能發揮到極致。上面我們針對 CPU 密集型和 I/O 密集型計算場景都給出了理論上的最佳公式,這些公式背后的目標其實就是將硬件的性能發揮到極致。

在 Java 領域,實現并發程序的主要手段就是多線程,使用多線程還是比較簡單的,但是使用多少個線程卻是個困難的問題。工作中,經常有人問,“各種線程池的線程數量調整成多少是合適的?”或者“Tomcat 的線程數、Jdbc 連接池的連接數是多少?”等等。那我們應該如何設置合適的線程數呢?

要解決這個問題,首先要分析以下兩個問題:

  1. 為什么要使用多線程?
  2. 多線程的應用場景有哪些?

為什么要使用多線程?

使用多線程,本質上就是提升程序性能。不過此刻談到的性能,可能在你腦海里還是比較籠統的,基本上就是快、快、快,這種無法度量的感性認識很不科學,所以在提升性能之前,首要問題是:如何度量性能。

度量性能的指標有很多,但是有兩個指標是最核心的,它們就是延遲和吞吐量。延遲指的是發出請求到收到響應這個過程的時間;延遲越短,意味著程序執行得越快,性能也就越好。 吞吐量指的是在單位時間內能處理請求的數量;吞吐量越大,意味著程序能處理的請求越多,性能也就越好。這兩個指標內部有一定的聯系(同等條件下,延遲越短,吞吐量越大),但是由于它們隸屬不同的維度(一個是時間維度,一個是空間維度),并不能互相轉換。

我們所謂提升性能,從度量的角度,主要是降低延遲,提高吞吐量。這也是我們使用多線程的主要目的。那我們該怎么降低延遲,提高吞吐量呢?這個就要從多線程的應用場景說起了。

多線程的應用場景

要想“降低延遲,提高吞吐量”,對應的方法呢,基本上有兩個方向,一個方向是優化算法,另一個方向是將硬件的性能發揮到極致。前者屬于算法范疇,后者則是和并發編程息息相關了。那計算機主要有哪些硬件呢?主要是兩類:一個是 I/O,一個是 CPU。簡言之,在并發編程領域,提升性能本質上就是提升硬件的利用率,再具體點來說,就是提升 I/O 的利用率和 CPU 的利用率。

我們的并發程序,需要 CPU 和 I/O 設備相互配合工作,也就是說,我們需要解決 CPU 和 I/O 設備綜合利用率的問題。

下面我們用一個簡單的示例來說明:如何利用多線程來提升 CPU 和 I/O 設備的利用率?假設程序按照 CPU 計算和 I/O 操作交叉執行的方式運行,而且 CPU 計算和 I/O 操作的耗時是 1:1。

如下圖所示,如果只有一個線程,執行 CPU 計算的時候,I/O 設備空閑;執行 I/O 操作的時候,CPU 空閑,所以 CPU 的利用率和 I/O 設備的利用率都是 50%。

單線程執行示意圖單線程執行示意圖

如果有兩個線程,如下圖所示,當線程 A 執行 CPU 計算的時候,線程 B 執行 I/O 操作;當線程 A 執行 I/O 操作的時候,線程 B 執行 CPU 計算,這樣 CPU 的利用率和 I/O 設備的利用率就都達到了 100%。

二線程執行示意圖二線程執行示意圖

我們將 CPU 的利用率和 I/O 設備的利用率都提升到了 100%,會對性能產生了哪些影響呢?通過上面的圖示,很容易看出:單位時間處理的請求數量翻了一番,也就是說吞吐量提高了 1 倍。此時可以逆向思維一下,如果 CPU 和 I/O 設備的利用率都很低,那么可以嘗試通過增加線程來提高吞吐量。

創建多少線程合適?

創建多少線程合適,要看多線程具體的應用場景。我們的程序一般都是 CPU 計算和 I/O 操作交叉執行的,由于 I/O 設備的速度相對于 CPU 來說都很慢,所以大部分情況下,I/O 操作執行的時間相對于 CPU 計算來說都非常長,這種場景我們一般都稱為 I/O 密集型計算;和 I/O 密集型計算相對的就是 CPU 密集型計算了,CPU 密集型計算大部分場景下都是純 CPU 計算。I/O 密集型程序和 CPU 密集型程序,計算最佳線程數的方法是不同的。

下面我們對這兩個場景分別說明。

對于 CPU 密集型計算,多線程本質上是提升多核 CPU 的利用率,所以對于一個 4 核的 CPU,每個核一個線程,理論上創建 4 個線程就可以了,再多創建線程也只是增加線程切換的成本。所以,對于 CPU 密集型的計算場景,理論上“線程的數量 =CPU 核數”就是最合適的。不過在工程上,線程的數量一般會設置為“CPU 核數 +1”,這樣的話,當線程因為偶爾的內存頁失效或其他原因導致阻塞時,這個額外的線程可以頂上,從而保證 CPU 的利用率。

對于 I/O 密集型的計算場景,比如前面我們的例子中,如果 CPU 計算和 I/O 操作的耗時是 1:1,那么 2 個線程是最合適的。如果 CPU 計算和 I/O 操作的耗時是 1:2,那多少個線程合適呢?是 3 個線程,如下圖所示:CPU 在 A、B、C 三個線程之間切換,對于線程 A,當 CPU 從 B、C 切換回來時,線程 A 正好執行完 I/O 操作。這樣 CPU 和 I/O 設備的利用率都達到了 100%。

三線程執行示意圖三線程執行示意圖

通過上面這個例子,我們會發現,對于 I/O 密集型計算場景,最佳的線程數是與程序中 CPU 計算和 I/O 操作的耗時比相關的,我們可以總結出這樣一個公式:

最佳線程數 =1 +(I/O 耗時 / CPU 耗時)

我們令 R=I/O 耗時 / CPU 耗時,綜合上圖,可以這樣理解:當線程 A 執行 IO 操作時,另外 R 個線程正好執行完各自的 CPU 計算。這樣 CPU 的利用率就達到了 100%。

不過上面這個公式是針對單核 CPU 的,至于多核 CPU,也很簡單,只需要等比擴大就可以了,計算公式如下:

最佳線程數 =CPU 核數 * [ 1 +(I/O 耗時 / CPU 耗時)]

總結

很多人都知道線程數不是越多越好,但是設置多少是合適的,卻又拿不定主意。其實只要把握住一條原則就可以了,這條原則就是將硬件的性能發揮到極致。上面我們針對 CPU 密集型和 I/O 密集型計算場景都給出了理論上的最佳公式,這些公式背后的目標其實就是將硬件的性能發揮到極致。

對于 I/O 密集型計算場景,I/O 耗時和 CPU 耗時的比值是一個關鍵參數,不幸的是這個參數是未知的,而且是動態變化的,所以工程上,我們要估算這個參數,然后做各種不同場景下的壓測來驗證我們的估計。不過工程上,原則還是將硬件的性能發揮到極致,所以壓測時,我們需要重點關注 CPU、I/O 設備的利用率和性能指標(響應時間、吞吐量)之間的關系。

課后思考

有些開發人員對于最佳線程數的設置積累了一些經驗值,認為對于 I/O 密集型應用,最佳線程數應該為:2 * CPU 的核數 + 1,你覺得這個經驗值合理嗎?

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2022-03-21 12:45:28

Java線程代碼

2010-03-18 15:31:13

Java創建線程

2010-03-15 17:56:23

Java多線程

2020-09-08 10:56:55

Java多線程存儲器

2023-12-20 10:04:45

線程池Java

2009-06-29 17:54:10

Java多線程Thread類創建線程

2024-06-27 08:04:39

2009-06-29 18:00:05

Java多線程Runnable接口創建線程

2022-03-14 08:02:08

輕量級動態線程池

2019-10-10 11:50:38

Java線程開發

2023-02-24 14:46:32

Java線程池編程

2010-03-18 15:47:07

Java創建線程

2020-06-16 11:00:40

線程Java代碼

2023-08-28 07:39:49

線程調度基本單位

2024-11-06 08:49:46

2023-09-04 08:08:59

2025-05-12 04:00:01

2021-02-25 15:58:46

C++線程編程開發技術

2023-12-07 07:28:25

線程共享資源

2011-10-18 17:00:02

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 天天影视色综合 | av日韩在线播放 | 久久久精 | 91精品久久久久 | 男女精品久久 | 成人一区二区三区在线观看 | 国产精品精品视频一区二区三区 | 欧美一区二区三区在线 | 欧美啪啪 | 亚洲在线视频 | 午夜电影合集 | 免费在线视频a | 亚洲第一成年免费网站 | 欧美一卡二卡在线观看 | 久国产精品| 国产精品美女久久久久aⅴ国产馆 | 亚洲精品综合 | 亚洲一区二区三区高清 | 成av在线 | 国产一区二区三区视频免费观看 | 国产日韩欧美 | 一级毛片,一级毛片 | 中文字幕影院 | 日日干夜夜草 | 激情综合五月 | 青青草原综合久久大伊人精品 | 黄色毛片一级 | 国产精品久久久 | 天天天操| 国内精品久久久久久 | 亚洲色欲色欲www | www.免费看片.com| 日本韩国欧美在线观看 | 久在线| 欧美成人激情 | 国产一区二区视频在线观看 | 性色av网站 | 91精品福利| 亚洲欧洲一区二区 | 亚洲中午字幕 | 玖玖国产 |