Java Thread之start和run方法的區別


原創轉載請注明出處:https://www.cnblogs.com/agilestyle/p/11421515.html

 

start

用start方法來啟動線程,真正實現了多線程運行,這時無需等待run方法體代碼執行完畢而直接繼續執行下面的代碼。通過調用Thread類的start()方法來啟動一個線程,這時此線程處於就緒(可運行)狀態,並沒有運行,一旦得到cpu時間片,就開始執行run()方法,這里方法run()稱為線程體,它包含了要執行的這個線程的內容,run方法運行結束,此線程隨即終止。

start方法源碼示例

一個 Java 線程的創建本質上就對應了一個本地線程(native thread)的創建,兩者是一一對應的。

關鍵問題是:本地線程執行的應該是本地代碼,而 Java 線程提供的線程函數(run)是 Java 方法,編譯出的是 Java 字節碼。

所以, Java 線程其實提供了一個統一的線程函數,該線程函數通過 Java 虛擬機調用 Java 線程方法 , 這是通過 Java 本地方法 start0 調用來實現的。 

也就是新創建的線程啟動調用native start0方法,而這些native方法的注冊是在Thread對象初始化的時候完成的

Thread 類有個 registerNatives 本地方法,該方法主要的作用就是注冊一些本地方法供 Thread 類使用,如 start0(),stop0() 等等,可以說,所有操作本地線程的本地方法都是由它注冊的。

這個方法放在一個 static 語句塊中,當該類被加載到 JVM 中的時候,它就會被調用,進而注冊相應的本地方法。(查看本地方法的源碼需要前往 http://jdk.java.net/java-se-ri/8 下載openjdk的源代碼)

而本地方法 registerNatives 是定義在 Thread.c 文件中的。Thread.c 是個很小的文件,它定義了各個操作系統平台都要用到的關於線程的公用數據和操作,如下: 

可以看出 Java 線程調用 start->start0 的方法,實際上會調用到 JVM_StartThread 方法,而 JVM_StartThread 最終調用的是 Java 線程的 run 方法。

在 jvm.cpp 中,有如下代碼段:

這里 JVM_ENTRY 是一個宏,用來定義 JVM_StartThread 函數,可以看到函數內創建了真正的平台相關的本地線程,其線程函數是 thread_entry,如下:

可以看到調用了 vmSymbols::run_method_name 方法,而 run_method_name 是在 vmSymbols.hpp 用宏定義的: 

 

run

run()方法只是類的一個普通方法而已,如果直接調用Run方法,程序中依然只有主線程這一個線程,其程序執行路徑還是只有一條,還是要順序執行,還是要等待run方法體執行完畢后才可繼續執行下面的代碼,這樣就沒有達到寫線程的目的。

run方法源碼示例

分別測試start和run

 1 package org.fool.test.thread;  
 2   
 3 public class ThreadTest {  
 4     public static void main(String[] args) {  
 5         Thread thread = new Thread(new Runnable() {  
 6             @Override  
 7             public void run() {  
 8                 System.out.println(Thread.currentThread().getName() + " invoked...");  
 9             }  
10         });  
11         thread.start();  
12         //thread.run();  
13     }  
14 }  

先運行thread.start()

Thread-0 invoked...  

注釋調thread.start()方法,運行thread.run()

main invoked... 

 

Summary

start方法可啟動多線程

run方法只是thread的一個普通方法調用,還是在主線程里執行,是不會開啟多線程的

 


免責聲明!

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



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