Java里一個線程兩次調用start()方法會出現什么情況


  這里有一道經典的面試題:“一個線程兩次調用start()方法會出現什么情況?”,咱們這次結合案例從線程源碼的角度炒剩飯。

  答:Java的線程是不允許啟動兩次的,第二次調用時,線程可能處於終止或者其它(非NEW)狀態,必然會拋出IllegalThreadStateException,這是一種運行時異常,多次調用start被認為是編程錯誤。如果業務需要線程run中的代碼再次執行,請重新啟動一個線程實例。

  應聘的時候回答這么多就可以了,下面從源碼角度深入分析為什么不行,如果面試官刨根問底,咱們也可以底氣十足。

案例分析

package com.sc.register;

/**
 * 在同一線程上兩次調用start方法
 *
 * @author Wiener
 * @date 2021/4/9
 */
public class ReStartThread implements Runnable {
    @Override
    public void run() {
        System.out.println("In run() method.");
    }

    public static void main(String[] args) {
        ReStartThread obj = new ReStartThread();
        Thread thread1 = new Thread(obj, "Thread-ReStart");
        thread1.start();
        System.out.println("當前線程狀態是:" + thread1.getState());
        // will throw java.lang.IllegalThreadStateException at runtime
        thread1.start();
    }
}

  執行結果如下:

當前線程狀態是:RUNNABLE
in run() method, method completed.
Exception in thread "main" java.lang.IllegalThreadStateException
	at java.base/java.lang.Thread.start(Thread.java:794)
	at com.sc.register.ReStartThread.main(ReStartThread.java:22)

Process finished with exit code 1

線程源碼分析

  Thread類中,start()函數第一行代碼就是校驗線程狀態,如果狀態不是新建,則拋出運行時異常IllegalThreadStateException,而且備注里有聲明:

    /**
     * Java thread status for tools, default indicates thread 'not yet started'
     */
    private volatile int threadStatus;
    
    public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException(); // ①

  在①處打斷點,以debug模式啟動案例,可以看到第二個start()執行后,線程狀態 threadStatus 不為0,故拋出異常。調試結果如下圖所示:

  溫馨提示:threadStatus的值在不同機器的運行結果可能不一樣。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM