Java線程池高頻面試題總結
1、在啟動線程時,為什麼要通過調用方法start執行方法run,而不能直接執行方法run?
調用方法start執行方法run,才是多線程的工作,**如果直接執行方法run,會被當成一個主線程下的普通方法執行,**而不會在某個線程中執行,因此不是多線程工作。
2、方法sleep、join和yield的區別有哪些?
方法sleep的作用是使當前線程暫停執行一段時間,讓其他線程有機會繼續執行;
方法join的作用是阻塞調用該方法的線程,直到當前線程執行完畢後,調用該方法的線程才能繼續執行;
方法yield的作用是暫停當前正在執行的線程對象,並執行其他線程。
3.為什麼方法wait、notify和notifyAll在Object類定義,而不在Thread類定義?
其中主要的原因是:
方法 wait、notify 和 notifyAll 不隻是普通方法或同步工具,它們還是 Java 中兩個線程之間的通信機制。對語言設計者而言, 如果不能通過 Java 關鍵字(例如 synchronized)實現通信機制,同時又要確保這個機制對每個對象可用,那麼 Object 類則是的合理的聲明位置。每個對象都可上鎖,因此方法 wait 和 notify 在 Object 類而不是 Thread 類定義。
4、終止線程應該使用什麼方法?為什麼不推薦使用stop和destroy方法來終止線程?
終止線程應該使用方法interrupt,使用方法stop會帶來兩個問題,
一是清理性工作無法完成;
二是會立即釋放所有鎖,導致對象狀態不一致。因此會造成不安全。
而方法destroy除瞭拋出NoSuchMethodError 以外沒有做任何事情,因此無法終止線程。
5、什麼是線程池?
線程池是一種線程的使用模式,創建若幹個可執行的線程放入一個池(容器)中,有任務需要處理時,會提交到線程池中的任務隊列,處理完後線程並不會被銷毀,而是仍然在線程池中等待下一個任務。
6、追問:線程池的好處有哪些?
使用線程池有以下三點好處:
- 降低資源消耗,重復利用線程池中已經創建的資源,可以避免頻繁的創建和銷毀線程,從而減少資源的消耗。
- 提高響應速度,由於線程池中有已經創建的線程,因此當任務到達時可以直接執行。不需要等待線程的創建。
- 提高線程的可管理性,線程是稀缺資源,如果無限制的創建,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一分配、調優和監控。
7、說一說線程池是如何創建的?
線程池的創建可以通過ThreadPoolExecutor類,
ThreadPoolExecutor類有4個構造方法,其中最一般話的構造方法包含7個參數。
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
這7個參數的含義分別是:
corePoolSize
: 核心線程數,定義瞭最少可以同時運行的線程數量,當有新的任務時就會創建一個線程執行任務,當線程池中的線程數量達到corePoolSize 之後,到達的任務進入阻塞隊列maximumPoolSize
: 最大線程數,定義瞭線程池中最多能創建的線程數量。keepAliveTime
: 等待時間,當線程池中的線程數量大於 corePoolSize 時,如果一個線程的空閑時間達到keepAliveTime 時則會終止,直到線程池中的線程數不超過 corePoolSize。unit
: 參數keepAliveTime 的單位。workQueue
: 阻塞隊列,用來存儲等待執行的任務。threadFactory
: 創建線程的工廠。handler
: 當拒絕處理任務時的策略。
8、向線程池提交任務的流程是什麼?
- 如果正在運行的線程數量小於corePoolSize,則創建核心線程運行這個任務。
- 如果正在運行的線程數量大於或等於corePoolSize,則將這個任務放入阻塞隊列。
- 如果阻塞隊列滿瞭,而且正在運行的線程數量小於maximumPoolSize,則創建非核心線程運行這個任務
- 如果阻塞隊列滿瞭,而且正在運行的線程數量大於或等於 maximumPoolSize,則線程池拋出RejectExecutionException 異常。
9、追問:說一說核心線程和非核心線程的區別?
核心線程和非核心線程的最大數目在創建線程時被鎖定,核心線程和非核心線程的區別如下:
- 向線程池提交任務時,首先創建核心線程運行任務,直到核心線程數達到上限,然後將任務放入阻塞隊列。
- 隻有在核心線程數到達上限,且阻塞隊列滿的情況下,才會創建非核心線程運行任務。
10、如何關閉線程池?
可以通過調用線程池的方法shutdown或shutdownNow關閉線程池,
這兩個方法的原理是 遍歷線程池中的工作線程,對每個工作線程調用 interrupt 方法中斷線程,無法響應中斷的任務可能永遠無法終止。
方法 shutDown 和 shutDownNow 有以下區別。
方法 shutDown 將線程池的狀態設置成 SHUTDOWN,正在執行的任務繼續執行,沒有執行的任務將中斷。
方法 shutDownNow 將線程池的狀態設置成 STOP,正在執行的任務被停止,沒有執行的任務被返回。
總結
多線程以及線程池相關的面試其實主要就是考察是否真正的使用過多線程和線程池開發,所以主要就是掌握多線程和線程池的創建和銷毀方法、瞭解線程池的原理。重點在於實踐。
本篇文章就到這裡瞭,希望能給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!