天天看點

問一下,線程池裡面到底該設定多少個線程?

每天淩晨00點00分, 第一時間與你相約

每日英文

No one can go to bear for you, no one can get to get you strong.

沒有人能夠去替你承受,也沒有人能夠拿得走你的堅強。

每日掏心話

有時候,雖然能想明白,但心裡就是接受不了。大道理人人都懂,小情緒卻難以自控。

來自:隻會一點java | 責編:樂樂

問一下,線程池裡面到底該設定多少個線程?

程式員小樂(ID:study_tech)第 951 次推文  圖源:百度

往日回顧:計算機網絡基礎知識總結

   正文   

關于如何計算并發線程數,一般分兩派,來自兩本書,且都是好書,到底哪個是對的?問題追蹤後,整理如下:

第一派:《Java Concurrency in Practice》即《java并發程式設計實踐》,如下圖:

問一下,線程池裡面到底該設定多少個線程?

如上圖,在《Java Concurrency in Practice》一書中,給出了估算線程池大小的公式:

Nthreads=NcpuUcpu(1+w/c),其中

Ncpu=CPU核心數

Ucpu=cpu使用率,0~1

W/C=等待時間與計算時間的比率

關注公衆号程式員小樂回複關鍵字“Java”擷取Java面試題和答案。

第二派:《Programming Concurrency on the JVM Mastering》即《Java 虛拟機并發程式設計》

問一下,線程池裡面到底該設定多少個線程?

線程數=Ncpu/(1-阻塞系數)

對于派系一,假設cpu100%運轉,即撇開CPU使用率這個因素,線程數=Ncpu*(1+w/c)。

現在假設将派系二的公式等于派系一公式,即Ncpu/(1-阻塞系數)=Ncpu*(1+w/c),===》阻塞系數=w/(w+c),即阻塞系數=阻塞時間/(阻塞時間+計算時間),這個結論在派系二後續中得到應征,如下圖:

由此可見,派系一和派系二其實是一個公式……這樣我就放心了……

那麼實際使用中并發線程數如何設定呢?分析如下(我們以派系一公式為例):

<code>Nthreads=Ncpu*(1+w/c)</code>

IO密集型:一般情況下,如果存在IO,那麼肯定w/c&gt;1(阻塞耗時一般都是計算耗時的很多倍),但是需要考慮系統記憶體有限(每開啟一個線程都需要記憶體空間),這裡需要上伺服器測試具體多少個線程數适合(CPU占比、線程數、總耗時、記憶體消耗)。如果不想去測試,保守點取1即,Nthreads=Ncpu*(1+1)=2Ncpu。這樣設定一般都OK。擴充一下:JAVA多線程和并發基礎面試問答

計算密集型:假設沒有等待w=0,則W/C=0. Nthreads=Ncpu。

至此結論就是:

IO密集型=2Ncpu(可以測試後自己控制大小,2Ncpu一般沒問題)(常出現于線程中:資料庫資料互動、檔案上傳下載下傳、網絡資料傳輸等等)

<code>計算密集型=Ncpu(常出現于線程中:複雜算法)</code>

java中:<code>Ncpu=Runtime.getRuntime().availableProcessors()</code>

關注公衆号程式員小樂回複關鍵字“offer”擷取算法面試題和答案。

當然派系一種《Java Concurrency in Practice》還有一種說法,

問一下,線程池裡面到底該設定多少個線程?

即對于計算密集型的任務,在擁有N個處理器的系統上,當線程池的大小為N+1時,通常能實作最優的效率。(即使當計算密集型的線程偶爾由于缺失故障或者其他原因而暫停時,這個額外的線程也能確定CPU的時鐘周期不會被浪費。)

即,計算密集型=Ncpu+1,但是這種做法導緻的多一個cpu上下文切換是否值得,這裡不考慮。讀者可自己考量。

選擇線程池并發線程數的因素很多:任務類型、記憶體等線程中使用到所有資源都需要考慮。

問一下,線程池裡面到底該設定多少個線程?

歡迎在留言區留下你的觀點,一起讨論提高。如果今天的文章讓你有新的啟發,歡迎轉發分享給更多人。歡迎加入程式員小樂技術交流群。

猜你還想看

阿裡、騰訊、百度、華為、京東最新面試題彙集

教你設計一個超牛逼的本地緩存!

Netty是個啥?簡單來說就這!

面試官:為什麼 wait() 方法需要寫在while裡、而不是if? 我回答不上來

問一下,線程池裡面到底該設定多少個線程?
問一下,線程池裡面到底該設定多少個線程?