Java線程池高頻面試題總結(jié)
1、在啟動(dòng)線程時(shí),為什么要通過(guò)調(diào)用方法start執(zhí)行方法run,而不能直接執(zhí)行方法run?
調(diào)用方法start執(zhí)行方法run,才是多線程的工作,**如果直接執(zhí)行方法run,會(huì)被當(dāng)成一個(gè)主線程下的普通方法執(zhí)行,**而不會(huì)在某個(gè)線程中執(zhí)行,因此不是多線程工作。
2、方法sleep、join和yield的區(qū)別有哪些?
方法sleep的作用是使當(dāng)前線程暫停執(zhí)行一段時(shí)間,讓其他線程有機(jī)會(huì)繼續(xù)執(zhí)行;
方法join的作用是阻塞調(diào)用該方法的線程,直到當(dāng)前線程執(zhí)行完畢后,調(diào)用該方法的線程才能繼續(xù)執(zhí)行;
方法yield的作用是暫停當(dāng)前正在執(zhí)行的線程對(duì)象,并執(zhí)行其他線程。
3.為什么方法wait、notify和notifyAll在Object類定義,而不在Thread類定義?
其中主要的原因是:
方法 wait、notify 和 notifyAll 不只是普通方法或同步工具,它們還是 Java 中兩個(gè)線程之間的通信機(jī)制。對(duì)語(yǔ)言設(shè)計(jì)者而言, 如果不能通過(guò) Java 關(guān)鍵字(例如 synchronized)實(shí)現(xiàn)通信機(jī)制,同時(shí)又要確保這個(gè)機(jī)制對(duì)每個(gè)對(duì)象可用,那么 Object 類則是的合理的聲明位置。每個(gè)對(duì)象都可上鎖,因此方法 wait 和 notify 在 Object 類而不是 Thread 類定義。
4、終止線程應(yīng)該使用什么方法?為什么不推薦使用stop和destroy方法來(lái)終止線程?
終止線程應(yīng)該使用方法interrupt,使用方法stop會(huì)帶來(lái)兩個(gè)問(wèn)題,
一是清理性工作無(wú)法完成;
二是會(huì)立即釋放所有鎖,導(dǎo)致對(duì)象狀態(tài)不一致。因此會(huì)造成不安全。
而方法destroy除了拋出NoSuchMethodError 以外沒(méi)有做任何事情,因此無(wú)法終止線程。
5、什么是線程池?
線程池是一種線程的使用模式,創(chuàng)建若干個(gè)可執(zhí)行的線程放入一個(gè)池(容器)中,有任務(wù)需要處理時(shí),會(huì)提交到線程池中的任務(wù)隊(duì)列,處理完后線程并不會(huì)被銷毀,而是仍然在線程池中等待下一個(gè)任務(wù)。
6、追問(wèn):線程池的好處有哪些?
使用線程池有以下三點(diǎn)好處:
- 降低資源消耗,重復(fù)利用線程池中已經(jīng)創(chuàng)建的資源,可以避免頻繁的創(chuàng)建和銷毀線程,從而減少資源的消耗。
- 提高響應(yīng)速度,由于線程池中有已經(jīng)創(chuàng)建的線程,因此當(dāng)任務(wù)到達(dá)時(shí)可以直接執(zhí)行。不需要等待線程的創(chuàng)建。
- 提高線程的可管理性,線程是稀缺資源,如果無(wú)限制的創(chuàng)建,不僅會(huì)消耗系統(tǒng)資源,還會(huì)降低系統(tǒng)的穩(wěn)定性,使用線程池可以進(jìn)行統(tǒng)一分配、調(diào)優(yōu)和監(jiān)控。
7、說(shuō)一說(shuō)線程池是如何創(chuàng)建的?
線程池的創(chuàng)建可以通過(guò)ThreadPoolExecutor類,
ThreadPoolExecutor類有4個(gè)構(gòu)造方法,其中最一般話的構(gòu)造方法包含7個(gè)參數(shù)。
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
這7個(gè)參數(shù)的含義分別是:
corePoolSize: 核心線程數(shù),定義了最少可以同時(shí)運(yùn)行的線程數(shù)量,當(dāng)有新的任務(wù)時(shí)就會(huì)創(chuàng)建一個(gè)線程執(zhí)行任務(wù),當(dāng)線程池中的線程數(shù)量達(dá)到corePoolSize 之后,到達(dá)的任務(wù)進(jìn)入阻塞隊(duì)列maximumPoolSize: 最大線程數(shù),定義了線程池中最多能創(chuàng)建的線程數(shù)量。keepAliveTime: 等待時(shí)間,當(dāng)線程池中的線程數(shù)量大于 corePoolSize 時(shí),如果一個(gè)線程的空閑時(shí)間達(dá)到keepAliveTime 時(shí)則會(huì)終止,直到線程池中的線程數(shù)不超過(guò) corePoolSize。unit: 參數(shù)keepAliveTime 的單位。workQueue: 阻塞隊(duì)列,用來(lái)存儲(chǔ)等待執(zhí)行的任務(wù)。threadFactory: 創(chuàng)建線程的工廠。handler: 當(dāng)拒絕處理任務(wù)時(shí)的策略。
8、向線程池提交任務(wù)的流程是什么?
- 如果正在運(yùn)行的線程數(shù)量小于corePoolSize,則創(chuàng)建核心線程運(yùn)行這個(gè)任務(wù)。
- 如果正在運(yùn)行的線程數(shù)量大于或等于corePoolSize,則將這個(gè)任務(wù)放入阻塞隊(duì)列。
- 如果阻塞隊(duì)列滿了,而且正在運(yùn)行的線程數(shù)量小于maximumPoolSize,則創(chuàng)建非核心線程運(yùn)行這個(gè)任務(wù)
- 如果阻塞隊(duì)列滿了,而且正在運(yùn)行的線程數(shù)量大于或等于 maximumPoolSize,則線程池拋出RejectExecutionException 異常。
9、追問(wèn):說(shuō)一說(shuō)核心線程和非核心線程的區(qū)別?
核心線程和非核心線程的最大數(shù)目在創(chuàng)建線程時(shí)被鎖定,核心線程和非核心線程的區(qū)別如下:
- 向線程池提交任務(wù)時(shí),首先創(chuàng)建核心線程運(yùn)行任務(wù),直到核心線程數(shù)達(dá)到上限,然后將任務(wù)放入阻塞隊(duì)列。
- 只有在核心線程數(shù)到達(dá)上限,且阻塞隊(duì)列滿的情況下,才會(huì)創(chuàng)建非核心線程運(yùn)行任務(wù)。
10、如何關(guān)閉線程池?
可以通過(guò)調(diào)用線程池的方法shutdown或shutdownNow關(guān)閉線程池,
這兩個(gè)方法的原理是 遍歷線程池中的工作線程,對(duì)每個(gè)工作線程調(diào)用 interrupt 方法中斷線程,無(wú)法響應(yīng)中斷的任務(wù)可能永遠(yuǎn)無(wú)法終止。
方法 shutDown 和 shutDownNow 有以下區(qū)別。
方法 shutDown 將線程池的狀態(tài)設(shè)置成 SHUTDOWN,正在執(zhí)行的任務(wù)繼續(xù)執(zhí)行,沒(méi)有執(zhí)行的任務(wù)將中斷。
方法 shutDownNow 將線程池的狀態(tài)設(shè)置成 STOP,正在執(zhí)行的任務(wù)被停止,沒(méi)有執(zhí)行的任務(wù)被返回。
總結(jié)
多線程以及線程池相關(guān)的面試其實(shí)主要就是考察是否真正的使用過(guò)多線程和線程池開(kāi)發(fā),所以主要就是掌握多線程和線程池的創(chuàng)建和銷毀方法、了解線程池的原理。重點(diǎn)在于實(shí)踐。
本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Springboot并發(fā)調(diào)優(yōu)之大事務(wù)和長(zhǎng)連接
這篇文章主要介紹了Springboot并發(fā)調(diào)優(yōu)之大事務(wù)和長(zhǎng)連接,重點(diǎn)分享長(zhǎng)事務(wù)以及長(zhǎng)連接導(dǎo)致的并發(fā)排查和優(yōu)化思路和示例,具有一定的參考價(jià)值,感興趣的可以了解一下2022-05-05
SpringBoot 中實(shí)現(xiàn)跨域的5種方式小結(jié)
這篇文章主要介紹了SpringBoot 中實(shí)現(xiàn)跨域的5種方式小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
淺談JAVA版本號(hào)的問(wèn)題 Java版本號(hào)與JDk版本
這篇文章主要介紹了淺談JAVA版本號(hào)的問(wèn)題 Java版本號(hào)與JDk版本,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
Spring的CorsFilter會(huì)失效的原因及解決方法
眾所周知CorsFilter是Spring提供的跨域過(guò)濾器,我們可能會(huì)做以下的配置,基本上就是允許任何跨域請(qǐng)求,我利用Spring的CorsFilter做跨域操作但是出現(xiàn)報(bào)錯(cuò),接下來(lái)小編就給大家介紹一Spring的CorsFilter會(huì)失效的原因及解決方法,需要的朋友可以參考下2023-09-09
Java中spring boot 字符串判斷是否為空方法小結(jié)
這篇文章主要介紹了Java中spring boot字符串判斷是否為空,通過(guò)安裝依賴,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-11-11
如何優(yōu)雅的拋出Spring Boot注解的異常詳解
這篇文章主要給大家介紹了關(guān)于如何優(yōu)雅的拋出Spring Boot注解的異常的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12
thymeleaf實(shí)現(xiàn)前后端數(shù)據(jù)交換的示例詳解
Thymeleaf?是一款用于渲染?XML/XHTML/HTML5?內(nèi)容的模板引擎,當(dāng)通過(guò)?Web?應(yīng)用程序訪問(wèn)時(shí),Thymeleaf?會(huì)動(dòng)態(tài)地替換掉靜態(tài)內(nèi)容,使頁(yè)面動(dòng)態(tài)顯示,這篇文章主要介紹了thymeleaf實(shí)現(xiàn)前后端數(shù)據(jù)交換,需要的朋友可以參考下2022-07-07
SpringBoot快速整合RabbitMq小案例(使用步驟)
這篇文章主要介紹了SpringBoot快速整合RabbitMq小案例,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
利用javadoc注釋自動(dòng)生成Swagger注解
由于現(xiàn)在controller方法上面沒(méi)有swagger注解,只能拿到接口url地址,無(wú)法獲得接口功能描述,所以本文為大家介紹一下如何利用javadoc注釋自動(dòng)生成Swagger注解,感興趣的可以了解下2023-08-08

