1. 什么是線程,線程和進(jìn)程有什么區(qū)別?
- 線程是程序的最小執(zhí)行單元;進(jìn)程是在內(nèi)存中運(yùn)行的應(yīng)用程序,一個進(jìn)程可能包含若干個線程。
2. 什么是用戶線程,什么是守護(hù)線程?
- 用戶線程就是運(yùn)行在前臺執(zhí)行具體任務(wù)的線程;守護(hù)線程就是運(yùn)行在后臺為其他線程提供基礎(chǔ)服務(wù)的,比如GC所在的線程。
3. 如何創(chuàng)建守護(hù)線程?
- 可以通過線程 start 之前調(diào)用 setDeamon(true) 方法來把線程設(shè)置為守護(hù)線程。
4. 守護(hù)線程有什么特點(diǎn)?
- 一旦所有的用戶線程結(jié)束,守護(hù)線程會隨著 JVM 一起結(jié)束工作,所以守護(hù)線程中的 finally 塊不一定執(zhí)行;
- 守護(hù)線程中創(chuàng)建的新線程也是守護(hù)線程。
5. 創(chuàng)建線程有哪些方式?
- 繼承 Thread 類;
- 實現(xiàn) Runnable 接口;
- 實現(xiàn) Callable 接口;
- 通過線程池獲取。
6. 說一說線程的生命周期。
被創(chuàng)建 ---> 就緒 ---> 運(yùn)行 ---> 阻塞 ---> 死亡。
- 被創(chuàng)建是線程剛被 new 出來;
- 就緒就是調(diào)用了 start 方法等待 cpu 的執(zhí)行權(quán);
- 運(yùn)行就是就緒狀態(tài)的線程獲得了 cpu 時間片;
- 阻塞就是運(yùn)行狀態(tài)的線程由于某些原因放棄了 cpu 的執(zhí)行權(quán);
- 死亡就是線程正?;蛘弋惓=Y(jié)束,退出了 run 方法,線程就死亡了,死亡的線程不能復(fù)生。
7. 你知道線程怎么設(shè)置優(yōu)先級嗎?
- 線程默認(rèn)優(yōu)先級是 5,可以通過 setPriority 方法設(shè)置,范圍是 1 ~ 100。
8. 什么是線程調(diào)度器?
- 是一個操作系統(tǒng)服務(wù),負(fù)責(zé)為就緒狀態(tài)的線程分配 CPU 時間,就緒狀態(tài)的線程必須依賴線程調(diào)度器才能獲得執(zhí)行權(quán)。
9. 什么叫時間分片?
- 將可用的 cpu 時間分配給就緒狀態(tài)的線程的過程。
10. 你知道哪些線程調(diào)度算法?
常見的有分時調(diào)度和搶占式調(diào)度兩種算法。
- 分時調(diào)度就是讓線程輪流獲得 CPU 的執(zhí)行權(quán),并且平均分配每個線程的時間片;
- 搶占式調(diào)度就是可以為線程設(shè)置優(yōu)先級,優(yōu)先級高的優(yōu)先獲得執(zhí)行權(quán),優(yōu)先級相同的隨機(jī)選擇一個線程執(zhí)行,JVM 采用的就是這種調(diào)度方式。
11. 哪些情況下線程會終止?
- 時間片用完;
- 優(yōu)先級更高的線程出現(xiàn);
- IO 操作受阻;
- 調(diào)用 sleep 方法進(jìn)入了休眠狀態(tài);
- 調(diào)用 yield 讓出了 CPU 執(zhí)行權(quán)。
12. 線程間怎么通信?
- wait 和 notify;
- await 和 signal;
- park 和 unpark。
13. 什么是線程的同步和互斥?
- 線程的互斥就是操作共享數(shù)據(jù)時的排他性,共享數(shù)據(jù)在同一時刻只能被一個線程操作;
- 線程的同步是在互斥的基礎(chǔ)上,通過一些機(jī)制來實現(xiàn)多個線程對資源的有序訪問。
14. 有哪些方式來實現(xiàn)線程的同步?
- 臨界區(qū):通過對多線程的串行化來訪問公共資源或一段代碼;
- 互斥對象:只有擁有互斥對象的線程才有訪問公共資源的權(quán)限;
- 信號量:它允許多個線程在同一時刻訪問同一資源,但是需要限制在同一時刻訪問此資源的最大線程數(shù)目;
- 事件對象:通過通知的方式來保持線程的同步。
15. java 中實現(xiàn)線程同步的方式有哪些?
- 同步方法、同步代碼塊、volatile、并發(fā)包中的 Lock、ThreadLocal、阻塞隊列、原子變量。
16. 線程的 run 和 start 方法有什么區(qū)別?
- 調(diào)用 run 方法相當(dāng)于在當(dāng)前線程調(diào)用了一個普通的方法,并不會創(chuàng)建新線程,調(diào)用 start 方法才會創(chuàng)建新線程。
17. 用過 wait 和 notify 嗎,說說你對它們的了解?
- wait 和 notify 可以實現(xiàn)線程間的等待喚醒。它們被定義在 Object 類中,因為任意對象都能做鎖對象,而 wait 和 notify 就是被鎖對象調(diào)用的,為了能被任意對象調(diào)用,所以只能定義在 Object 類中。wait 和 notify 被調(diào)用的前提是持有鎖,所以一定得在同步代碼塊或者同步方法中調(diào)用。wait 的時候一定要用 while 循環(huán)去判斷,不能用 if,否則可能會收到虛假喚醒。
18. yield 方法有什么作用?
- yield 方法是當(dāng)前線程讓出自己的執(zhí)行權(quán),重新進(jìn)入就緒狀態(tài),當(dāng)然進(jìn)入就緒狀態(tài)后也有可能又是自己搶到了執(zhí)行權(quán)。
19. servlet 線程是否安全?
- servlet 單例多線程,線程不安全;
- struts 多實例多線程,線程安全;
- springMVC 單實例多線程,線程不安全。