java面試題 --- 線程

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 單實例多線程,線程不安全。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容