Java線程池的參數設置


最近面試過一些候選人,面試過程中,我比較傾向於問一些偏基礎又較為開放的問題,用來看看候選人基礎能力怎么樣,比如線程池,提問過程一般類似如下:

我先問候選人平時怎么使用線程池,得到的結果不出意外就是兩種:1.我不用線程池,工作中沒接觸過並發;2.用Executors.newCachedThreadPool;

不管是哪一種回答,我還是希望能從候選人那里得到他們對線程池的理解,因此還是會問一下ThreadPoolExecutorService的幾個參數相關的問題,除了基礎非常差的候選人外,一般候選人都能回答上corePoolSize, maxPoolSize, BlockingQueue之間的關系:

  • corePoolSize是核心線程數,maxPoolSize是最大線程數,BlockingQueue是任務隊列
  • 當有任務提交時,先創建corePoolSize數量的線程,有更多的任務則進入到BlockingQueue,BlockingQueue滿了還不夠則創建線程數直到macPoolSize
  • 線程空閑一段時間后會被銷毀直到線程池中只剩下core數量的線程

回答出這幾個參數的作用以及他們之間的關系后,我一般會給一到兩個線程池相關的題,看看候選人是否能思考出,比如:

  • 假如提交到線程池中的任務,IO耗時占比是90%,計算耗時占比10%,忽略提交到線程池中的任務數量,在4C8G的機器上,理想情況下線程池中創建多少個線程是最優的

一般平時只埋頭寫CURD的候選人,難以計算出來,當然也遇到了不少能算出來結果來的,線程數=(1/0.1) * 4 = 40,能算出來的候選人,我會問下其它問題,例如:

  • 假如e有一類cpu密集性的任務,沒有IO操作,日常的時候只有1個任務,流量高峰會有50個任務,4C8G的機器上,使用的線程池,如何設置corePoolSize, maxPoolSize以及BlockingQueue的大小

這樣的問題,我還沒有遇到能回答的候選人,一般得到類似於下的回答:

  • corePoolSize=4個線程,maxPoolSize大點100個,隊列大點,1萬
  • 2個線程,隊列大點1千

因此我會對候選人做一些引導,比如回答core=4, max=50, queue=1w的,我會問他他設置的maxPoolSize有沒有作用,明顯隊列設置成1w,這個隊列太大,根本就不會滿,maxPoolSize數量的線程永遠不會被創建,明顯候選人是隨意設置的,沒有經過思考,這個時間我會讓他結合前面一個題再思考思考

這一步后,有些等候人開始回答出用4個線程,隊列50,但這樣並不是最優的,因為日常每秒1個任務時,只需要一個線程就夠了,創建出4個線程,就有3個浪費

很顯然,日常只需要一個線程,那么corePoolSize=1,而高峰時候,雖然任務有50個,但是只是4C的機器,對於cpu密集型任務,4個線程是最優的,因此理想情況下maxCorePoolSize=4,最后再看看隊列,因為隊列滿了,max才會被創建,而我們需要讓max快速被創建出來,又不會出現任務拒絕,因此,可將隊列大小設置成46,那么線程池的行為如下:

  • 提交第一個任務,創建出core,1個線程
  • 提交第二個到第47個任務時,這些任務進入到隊列中,此時隊列已滿
  • 提交第48個任務到第50個任務時,創建出max,此時一共有4個線程
  • 4個線程同時將隊列里的46個任務消費完
  • 一段時間后,max - core數量的線程銷毀,即銷毀3個線程,還剩下一個線程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM