1. 程式人生 > >面試被問執行緒池,真香

面試被問執行緒池,真香

> 這篇是併發程式設計系列文章第五篇了,說到併發程式設計,怎麼少的了執行緒池,在阿里執行緒池使用場景非常多,用好執行緒池這個利器也算是日常開發必須掌握的了,下面講講2019年的那一夜,就執行緒池和某位面試官鏖戰了半個小時。 **面試官** : 看你簡歷上寫了對系統性能做了優化,能簡單給我介紹一下嗎? 都有哪些優化,你是怎麼衡量優化效果的? **我** : 巴拉巴拉。。。例如我們系統之前要查詢使用者的個人身份資訊、聯絡人資訊、訂單狀態資訊、積分資訊,之前系統是單執行緒序列處理的,我用執行緒池對四個任務並行處理,然後對處理結果合併。 **面試官** : 你剛才說用到執行緒池,能跟我講講為什麼用執行緒池嗎? 我建立四個執行緒處理可不可以? **我** : 可以,當然可以。 ![img](https://img-blog.csdnimg.cn/img_convert/b2686f5b8635e70b170454c00a2120cd.gif) **我** : 但是用執行緒池更合適。阿里巴巴開發規約中有一條: > 3.【強制】執行緒資源必須通過執行緒池提供,不允許在應用中自行顯式建立執行緒。 > 說明:使用執行緒池的好處是減少在建立和銷燬執行緒上所消耗的時間以及系統資源的開銷,解決資源不足的問題。如果不使用執行緒池,有可能造成系統建立大量同類執行緒而導致消耗完記憶體或者“過度切換”的問題。 **我** : 就像你去餐廳吃飯,服務員總是提前洗好盤子,不會等你來打飯的時候才洗盤子,盤子就像是執行緒池裡的執行緒,你打飯就是要處理的任務。 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2021020522083154.jpeg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nd2FuZ3p3,size_16,color_FFFFFF,t_70#pic_center) **面試官** : 那你知道執行緒池的類結構嗎? **我**: 這算什麼問題? 不應該是問我核心執行緒數怎麼設定嗎?好吧。。。請看下圖: ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20210205220841886.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nd2FuZ3p3,size_16,color_FFFFFF,t_70#pic_center) - Executor 的定義非常簡單,就定義了執行緒池最本質要做的事,執行任務。 ```java public interface Executor { void execute(Runnable command); } ``` - ExecutorService 也是個介面,不過他算是把執行緒池的框架搭出來了,告訴要實現它的執行緒池必須提供的一些管理執行緒池的方法。 - AbstractExecutorService 是普通的執行緒池執行器,ScheduledExecutorService 是定時任務執行緒池。 **面試官** : 那你日常開發中是怎麼建立執行緒池的? **我**: 我用`ThreadPoolExecutor` 自定義建立執行緒池。 **面試官** : 那你知道執行緒池建立時都有哪些引數嗎? **我**: 執行緒池主要的核心引數有7個,我們看 `ThreadPoolExecutor` 建構函式就知道了 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20210205220855785.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nd2FuZ3p3,size_16,color_FFFFFF,t_70#pic_center) 1. corePoolSize :核心執行緒數 2. maximumPoolSize: 最大執行緒數 3. keepAliveTime :執行緒線上程池中不被銷燬的空閒時間,如果執行緒池的執行緒太多,任務比較小,到這個時間就銷燬執行緒池。 unit : keepAliveTime 的時間單位,一般設定成秒或毫秒。 4. workQueue : 任務佇列,存放等待執行的任務 5. threadFactory: 建立執行緒的任務工廠,比如給執行緒命名加上字首,後面會講 6. handler : 拒絕任務處理器,當任務處理不過來時的拒絕處理器 7. allowCoreThreadTimeOut : 是否允許核心執行緒超時銷燬,這個引數不在建構函式中,但重要性也很高 **面試官** : 老實說,你是不是來之前背過了,不然怎麼可能都記住了。 **我**: [掀桌子],不面了,還找什麼工作,要什麼自行車。 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20210205220908435.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nd2FuZ3p3,size_16,color_FFFFFF,t_70#pic_center) ​ 我不過是來之前把“安琪拉的部落格”公眾號上的文章都看了個遍。 **面試官** : 其實剛才那也是問題,考察面試者是否皮實,我們繼續。。 **面試官** : 剛才說了這些核心引數,你能不能跟我講講執行緒池的基本工作原理。 **我**: 可以的,這裡我給你畫個流程,如下所示: ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20210205220920489.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nd2FuZ3p3,size_16,color_FFFFFF,t_70#pic_center) **面試官** : 那按照上面的流程寫段虛擬碼。 **我**: 還能不能好好面了,讓手撕執行緒池。 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20210205221128889.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nd2FuZ3p3,size_16,color_FFFFFF,t_70) 那好吧,你對著