發布時間:2024-01-24閱讀(14)
面試題1:ThreadPoolExecutor 有哪些常用的方法?
ThreadPoolExecutor有如下常用方法:
這些方法可以用來終止線程池、線程池監控等。
面試題2:說說submit(和 execute兩個方法有什么區別?
submit() 和 execute() 都是用來執行線程池的,只不過使用 execute() 執行線程池不能有返回方法,而使用 submit() 可以使用 Future 接收線程池執行的返回值。
面試題3:shutdownNow() 和 shutdown() 兩個方法有什么區別?
shutdownNow() 和 shutdown() 都是用來終止線程池的,它們的區別是,使用 shutdown() 程序不會報錯,也不會立即終止線程,它會等待線程池中的緩存任務執行完之后再退出,執行了 shutdown() 之后就不能給線程池添加新任務了;shutdownNow() 會試圖立馬停止任務,如果線程池中還有緩存任務正在執行,則會拋出 java.lang.InterruptedExceptIOn: sleep interrupted 異常。
面試題4:了解過線程池的工作原理嗎?

當線程池中有任務需要執行時,線程池會判斷如果線程數量沒有超過核心數量就會新建線程池進行任務執行,如果線程池中的線程數量已經超過核心線程數,這時候任務就會被放入任務隊列中排隊等待執行;如果任務隊列超過最大隊列數,并且線程池沒有達到最大線程數,就會新建線程來執行任務;如果超過了最大線程數,就會執行拒絕執行策略。
面試題5:線程池中核心線程數量大小怎么設置?
「CPU密集型任務」:比如像加解密,壓縮、計算等一系列需要大量耗費 CPU 資源的任務,大部分場景下都是純 CPU 計算。盡量使用較小的線程池,一般為CPU核心數 1。因為CPU密集型任務使得CPU使用率很高,若開過多的線程數,會造成CPU過度切換。
「IO密集型任務」:比如像 MySQL 數據庫、文件的讀寫、網絡通信等任務,這類任務不會特別消耗 CPU 資源,但是 IO 操作比較耗時,會占用比較多時間。可以使用稍大的線程池,一般為2*CPU核心數。IO密集型任務CPU使用率并不高,因此可以讓CPU在等待IO的時候有其他線程去處理別的任務,充分利用CPU時間。
另外:線程的平均工作時間所占比例越高,就需要越少的線程;線程的平均等待時間所占比例越高,就需要越多的線程;
以上只是理論值,實際項目中建議在本地或者測試環境進行多次調優,找到相對理想的值大小。
面試題6:線程池為什么需要使用(阻塞)隊列?
主要有三點:
面試題7:線程池為什么要使用阻塞隊列而不使用非阻塞隊列?
阻塞隊列可以保證任務隊列中沒有任務時阻塞獲取任務的線程,使得線程進入wait狀態,釋放cpu資源。
當隊列中有任務時才喚醒對應線程從隊列中取出消息進行執行。
使得在線程不至于一直占用cpu資源。
(線程執行完任務后通過循環再次從任務隊列中取出任務進行執行,代碼片段如下
while (task != null || (task = getTask()) != null) {})。
不用阻塞隊列也是可以的,不過實現起來比較麻煩而已,有好用的為啥不用呢?
面試題8:了解線程池狀態嗎?
通過獲取線程池狀態,可以判斷線程池是否是運行狀態、可否添加新的任務以及優雅地關閉線程池等。

面試題9:知道線程池中線程復用原理嗎?
線程池將線程和任務進行解耦,線程是線程,任務是任務,擺脫了之前通過 Thread 創建線程時的一個線程必須對應一個任務的限制。
在線程池中,同一個線程可以從阻塞隊列中不斷獲取新任務來執行,其核心原理在于線程池對 Thread 進行了封裝,并不是每次執行任務都會調用 Thread.start() 來創建新線程,而是讓每個線程去執行一個“循環任務”,在這個“循環任務”中不停的檢查是否有任務需要被執行,如果有則直接執行,也就是調用任務中的 run 方法,將 run 方法當成一個普通的方法執行,通過這種方式將只使用固定的線程就將所有任務的 run 方法串聯起來。
面試題10:說說線程池創建需要的那幾個核心參數的含義
ThreadPoolExecutor 最多包含以下七個參數:
本文通過沒有使用線程池帶來的弊端,Executors介紹,Executors的六種方法介紹、如何使用線程池,了解線程池原理,核心參數,以及10到線程池面試題。
「成功不是將來才有的,而是從決定去做的那一刻起,持續累積而成。」
歡迎分享轉載→http://www.avcorse.com/read-253683.html
Copyright ? 2024 有趣生活 All Rights Reserve吉ICP備19000289號-5 TXT地圖HTML地圖XML地圖