啟動線程

對比start方法與run方法

代碼部分

public class StartAndRunMethod {
    public static void main(String[] args) {
        Runnable printThreadName=()->{
            System.out.println(Thread.currentThread().getName());
        };
        new Thread(printThreadName).run();//result:main
        new Thread(printThreadName).start();//Thread-0
    }
}

正確啟動一個線程的方法應(yīng)該是使用start方法。
對比start方法與run方法的源碼,如下所示。

  1. run
    /**
     * If this thread was constructed using a separate
     * <code>Runnable</code> run object, then that
     * <code>Runnable</code> object's <code>run</code> method is called;
     * otherwise, this method does nothing and returns.
     * <p>
     * Subclasses of <code>Thread</code> should override this method.
     *
     * @see     #start()
     * @see     #stop()
     * @see     #Thread(ThreadGroup, Runnable, String)
     */
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
  1. start
    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();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

start方法主要關(guān)注try代碼塊中的代碼。從上可以看到如果是執(zhí)行run方法的話,那么就是主線程直接執(zhí)行了那段代碼塊,調(diào)用了target的run方法,所以結(jié)果肯定是Main。而start方法里面有一個關(guān)鍵函數(shù)調(diào)用start0,這一句是用來創(chuàng)建線程的,也就是說必須要先創(chuàng)建線程才行,所以必須要用start方法。
調(diào)用了start方法不一定就立刻會創(chuàng)建線程,這得根據(jù)JVM的調(diào)度算法來決定。

  • 不能重復(fù)調(diào)用start,否則會拋出異常java.lang.IllegalThreadStateException。
    再次閱讀start方法的代碼,可以看到start方法分為了三步:
    1. 檢查線程狀態(tài)
    2. 加入線程組
    3. 啟動線程
      在第一步中,如果線程狀態(tài)不為0(線程狀態(tài)為NEW)的話就會拋出java.lang.IllegalThreadStateException。
      另外start方法是被synchronized關(guān)鍵字修飾的,可以保證線程安全,main方法線程和system組的線程則是由JVM創(chuàng)建的,并不會通過start來啟動。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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