阿里高頻面試題:一個線程兩次調用start方法會出現什麼情況?


阿里高頻面試題:一個線程兩次調用start方法會出現什麼情況?


推薦回答

首先在Java中線程是不允許啟動兩次的,第二次調用會拋出IllegalThreadStateException,這是一種運行時異常,多次調用start被認為是編程錯誤。Thread類start方法源碼如下:

阿里高頻面試題:一個線程兩次調用start方法會出現什麼情況?

可以看出start方法是一個同步方法,並且在執行start方法時首先會判斷當前線程的運行狀態,只有在當前狀態為NEW的時候才會繼續執行,方法執行完畢或改變當前線程的狀態。如此設計保證了線程僅可執行一次start。

深入剖析

在回答完以上內容後,如果感覺面試官沒有讓你停下來的意思,可以繼續說下自己對於線程生命週期的理解。以下是對於線程生命週期的完整闡述,面試的時候可摘取必要部分進行闡述。

關於線程生命週期的不同狀態,在Java 5以後,線程狀態被明確定義在其公共內部枚舉類型java.lang.Thread.State中,分別是:

新建(NEW),表示線程被創建出來還沒真正啟動的狀態,可以認為它是個Java內部狀態。

就緒(RUNNABLE),表示該線程已經在JVM中執行,當然由於執行需要計算資源,它可能是正在運行,也可能還在等待系統分配給它CPU片段,在就緒隊列裡面排隊。

在其他一些分析中,會額外區分一種狀態RUNNING,但是從Java API的角度,並不能表示出來。

阻塞(BLOCKED),這個狀態和我們前面兩講介紹的同步非常相關,阻塞表示線程在等待Monitor lock。比如,線程試圖通過synchronized去獲取某個鎖,但是其他線程已經獨佔了,那麼當前線程就會處於阻塞狀態。

等待(WAITING),表示正在等待其他線程採取某些操作。一個常見的場景是類似生產者消費者模式,發現任務條件尚未滿足,就讓當前消費者線程等待(wait),另外的生產者線程去準備任務數據,然後通過類似notify等動作,通知消費線程可以繼續工作了。Thread.join()也會令線程進入等待狀態。

計時等待(TIMED_WAIT),其進入條件和等待狀態類似,但是調用的是存在超時條件的方法,比如wait或join等方法的指定超時版本,如下面示例:

public final native void wait(long timeout) throws InterruptedException;

終止(TERMINATED)

,不管是意外退出還是正常執行結束,線程已經完成使命,終止運行,也有人把這個狀態叫作死亡。

在第二次調用start()方法的時候,線程可能處於終止或者其他(非NEW)狀態,但是不論如何,都是不可以再次啟動的。

考點分析

這個問題可以算是個常見的面試熱身題目,不僅阿里,一些有技術積累的團隊也會有類似的問法。前面給出的推薦回答,算是對線程基本狀態和簡單流轉的一個簡單介紹,如果覺得還不夠直觀,請參考如下狀態圖進行演練。


阿里高頻面試題:一個線程兩次調用start方法會出現什麼情況?


總的來說,理解線程的內部原理對於我們日常開發或者診斷分析,都是不可或缺的。

面試官可能會以此為契機,從各種不同角度考察你對線程的掌握:

  1. 資深一點的面試官可能會問你線程到底是什麼以及Java底層實現線程的方式。
  2. 線程狀態的切換、線程安全以及併發工具類等方面的擴展。
  3. 多線程編程時容易踩的坑與體會等。

可以看出,僅僅是一個線程,就有非常多的內容需要掌握。我們在面試備戰過程中切忌浮躁,腳踏實地地把相關的知識點逐一攻克,還擔心沒有心儀大廠的offer嘛!


關注評論後可私信獲取更多最新大廠面試資料,如果你需要一線互聯網公司的內推機會(社招+校招),也可以私聊我哦


分享到:


相關文章: