new Thread與執行緒建立

貓毛·波拿巴發表於2018-09-06

 

概要:new Thread 並不意味著已經建立了一個執行緒,只能說明建立一個類的物件例項而已。而真正建立執行緒的是start()方法,此方法將呼叫本地方法start0()建立本地執行緒,而Thread的run()方法其實是作為一個回撥函式被JVM建立的執行緒所呼叫。

 

構造方法與執行緒建立有關嗎,它做了什麼?

我們還是來看看原始碼吧,看Thread的構造方法到底做了什麼,各構造過載方法都呼叫了init方法,而這段程式碼就是init方法的主要內容:

 

有上述程式碼可得,構造方法實現的內容無非就是繼承父執行緒的屬性,如是否是後臺執行緒,優先順序等,並生成一個執行緒名稱。僅此而已,並沒有任何與建立執行緒有關的操作。

 

執行緒是何時建立的?

由註釋可知,Start方法將建立一個執行緒(通過呼叫本地方法start0),然後JVM會利用新建立的本地執行緒回撥Thread物件的run方法。

JVM如何建立執行緒及回撥run方法,可參考這篇文章:Java建立執行緒的方法

 

不呼叫Thread物件的start()方法,而是直接呼叫run()方法會如何?

那結果就是沒有建立執行緒,而是在原呼叫執行緒執行run方法。

示例程式碼:

public class ThreadRunTest {
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(3); //延遲列印
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Task Completed");
            }
        };
        Thread t = new Thread(runnable);
        t.run();
        System.out.println("Main Thread print"); //如果t.run()是另外一個執行緒執行的話,此字串將先被輸出
    }
}

程式輸出:

此段程式碼中,run方法執行的執行緒仍然是Main主執行緒。與下述程式碼基本等價:

public class ThreadRunTest {
    public static void main(String[] args) {

        //begin
        try {
            TimeUnit.SECONDS.sleep(3); //延遲列印
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Task Completed");
        //end
        
        System.out.println("Main Thread print"); //如果t.run()是另外一個執行緒的話,此字串將先被輸出


    }
}

值得一提的是,Runable並沒有多麼神祕,它不過是一個很普通的介面,有一個run()方法,裡面只是要執行的程式碼塊。僅此而已。它的使用方式就是,把要執行的程式碼塊寫到run方法裡面去,然後找一個執行緒去執行這個方法,就這樣。

 

 

 

相關文章