查詢電腦的邏輯核心數,不一樣業務下如何配置線程池

邏輯核心數

通常百度如何獲取電腦的邏輯核心數,都會出現這段代碼:數據庫

Runtime.getRuntime().availableProcessors()
複製代碼

然而,問題在於Runtime.getRuntime().availableProcessors()也並不是都能返回你所指望的數值。好比說,在個人雙核1-2-1機器上,它返回的是2,這是對的。不過在個人1-4-2(1個物理處理器-4個核-每一個核2個超線程=也就是一般說的4核8線程)機器 上,也就是一個CPU插槽,4核,每一個核2個超線程,這樣的話會返回8。不過我其實只有4個核,若是代碼的瓶頸是在CPU這塊的話,我會有7個線程在同時 競爭CPU週期,而不是更合理的4個線程。若是個人瓶頸是在內存這的話,那這個測試我能夠得到7倍的性能提高。bash

不過這還沒完!Java Champions上的一個哥們發現了一種狀況,他有一臺16-4-2的機器 (也就是16個CPU插槽,每一個CPU4個核,每核兩個超線程,返回的值竟然是16!從個人i7 Macbook pro上的結果來看,我以爲應該返回的是1642=128。在這臺機器上運行Java 8的話,它只會將通用的FJ池的併發數設置成15。正如 Brian Goetz所指出的,「虛擬機其實不清楚什麼是處理器,它只是去請求操做系統返回一個值。一樣的,操做系統也不知道怎麼回事,它是去問的硬件設備。硬件會告訴它一個值,一般來講是硬件線程數。操做系統相信硬件說的,而虛擬機又相信操做系統說的。」網絡

因此不一樣業務下的狀況不盡相同,不能一律而論都根據核心數量去統一配置線程池。併發

那麼若是咱們線程池主要用於處理 IO 密集型的任務時,如讀取文件,數據庫鏈接,網絡通信等,咱們都知道 IO 讀寫的速度,與CPU相比的話,確定是慢的多,因此通常建議去機器邏輯核心數的 2 倍。性能

多個線程池

通常項目可能會建立多個線程池,由於好比2種業務,一種要求不高,可是數量極多,能夠重試,一種是數量小,要求及時,若是放在一塊兒,會由於多的數量可能影響你那筆少的,測試

線程池用來管理線程,通常須要一個定時線程池,一個業務線程池,一個io線程池,有的時候,定時線程池和業務線程池也能夠共用,好比netty的線程池就能夠共用。業務線程池用於處理核心業務,通常要求速度快,延遲低,而io線程池通常用於網絡交互,好比數據庫操做,rpc請求,或者磁盤讀寫。加密

業務場景

主要要先看咱們線程池用於執行的任務性質。若是該線程池主要用於處理計算密集型的任務時,如加密、大數分解等主要利用CPU資源的任務,通常建議將咱們的線程數設置爲機器的核心數(邏輯核心)+ 1spa

這裏爲何要進行加一呢?這是爲了不咱們CPU會出現頁缺失的狀況(頁缺失是指線程執行所需的數據還將來來的及加載,部分還存在於磁盤之上,那麼這個線程就會被掛起。)操作系統


那麼若是咱們線程池主要用於處理 IO 密集型的任務時,如讀取文件,數據庫鏈接,網絡通信等,咱們都知道 IO 讀寫的速度,與CPU相比的話,確定是慢的多,因此通常建議去機器邏輯核心數的 2 倍。線程

另外若是咱們線程池既處理計算密集型任務,也處理IO密集型任務時。那麼咱們應該如何處理?

IO 密集型所花費的時間遠大於計算密集型花費的時間,拆分意義不大,這時就沒有必要拆分;可是若是 IO 密集型花費的時間約等於計算密集型的時間,則建議將其拆分開來。

相關文章
相關標籤/搜索