當一個執行緒被啟動後,如果再次調start()方法,將會丟擲IllegalThreadStateException異常。
這是因為Java執行緒的生命週期只有一次。呼叫start()方法會導致系統在新執行緒中執行執行體,但是如果執行緒已經結束,則不能再次使用,需要重新建立一個新的執行緒物件並呼叫start()方法。
以下是程式碼示例:
public class ThreadTest { public static void main(String[] args) { Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("Thread started"); } }); // 第一次呼叫start方法 thread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // 第二次呼叫start方法,會丟擲IllegalThreadStateException異常 thread.start(); } }
上述程式碼中,我們在一個新的執行緒中啟動了一個執行體,並等待1秒鐘後再次呼叫 start()方法。在第二次呼叫start()方法時,由於該執行緒已經執行完畢,此時會丟擲IllegalThreadStateException異常。
測試結果:
Thread started Exception in thread "main" java.lang.IllegalThreadStateException at java.lang.Thread.start(Thread.java:708) at com.gmb.springcloud.ThreadTest.main(ThreadTest.java:20)
Java執行緒是一種作業系統級別的資源,執行緒的啟動和結束都需要涉及到對應的作業系統排程。在Java中,每個執行緒只能被啟動一次,並且一旦執行緒結束,它的狀態就不能再改變。這也是為什麼如果同一個執行緒物件呼叫了兩次start()方法會丟擲 IllegalThreadStateException異常的原因。
在底層實現上,當我們呼叫Thread類的start()方法時,JVM會首先檢查當前執行緒的狀態是否為NEW(新建)狀態,如果不是,則丟擲異常。如果當前執行緒狀態正確,則將該執行緒加入到排程佇列中等待作業系統排程執行。此時,執行緒的狀態會從NEW轉換為 RUNNABLE(可執行)狀態,並開始執行其中的run()方法。由於一個執行緒只能被執行一次,因此當我們嘗試再次呼叫start()方法時,JVM會檢測當前執行緒狀態是否處於已結束(TERMINATED)狀態或者死亡(DEAD)狀態。如果是,那麼該執行緒無法被重新啟動,因為該執行緒已經完成了所需的任務並退出了。
綜上所述,每個執行緒只能被啟動一次,不能重複啟動。這也是為什麼如果一個執行緒兩次呼叫start()方法就會丟擲異常的原因。
往期面試題:
Java面試題:@PostConstruct、init-method和afterPropertiesSet執行順序?
Java面試題:SimpleDateFormat是執行緒安全的嗎?使用時應該注意什麼?
Java面試題:細數ThreadLocal大坑,記憶體洩露本可避免
Java面試題:請談談對ThreadLocal的理解?
Java面試題:為什麼HashMap不建議使用物件作為Key?
Java面試題:你知道Spring的IOC嗎?那麼,它為什麼這麼重要呢?
Java面試題:執行緒池內“鬧情緒”的執行緒,怎麼辦?
Java面試題:Spring Bean執行緒安全?別擔心,只要你不寫併發程式碼就好了!