Java中多執行緒啟動,為什麼呼叫的是start方法,而不是run方法?
阿新 • • 發佈:2021-02-13
### 前言
大年初二,大家新年快樂,我又開始碼字了。寫這篇文章,源於在家和基友交流的時候,基友問到了,我猛然發現還真是這麼回事,多執行緒啟動呼叫的都是start,那麼為什麼沒人掉用run呢?於是開啟我的idea,翻一波程式碼,帶大家一探究竟。
### 繼承thread類實現多執行緒
我們知道java有三種方式實現多執行緒,這裡直接用繼承的方式進行試驗,其他方式同理。我們要做的是首先宣告一個執行緒。然後去呼叫,最終根據結果歸納run和start的區別。
定義一個執行緒類。
```
class MyThread extends Thread {
private String title;
public MyThread(String title) {
this.title = title;
}
@Override
public void run() {
for(int x = 0; x < 5 ; x++) {
System.out.println(this.title + "執行,x = " + x);
}
}
}
```
在我們的主類中,起三個執行緒,看看呼叫的結果。程式碼如下:
```
public class ExtendsThread {
public static void main(String[] args) {
new MyThread("執行緒A").start();
new MyThread("執行緒B").start();
new MyThread("執行緒C").start();
}
}
```
直接執行main方法。
觀察結果我們發現,三個執行緒隨機交替執行,取決於cpu的排程。
![](https://img2020.cnblogs.com/blog/1534147/202102/1534147-20210213110249051-163734549.png)
我們再使用run方法來進行呼叫,檢視結果
```
public class ExtendsThread {
public static void main(String[] args) {
new MyThread("執行緒A").run();
new MyThread("執行緒B").run();
new MyThread("執行緒C").run();
}
}
```
結果如下:
![](https://img2020.cnblogs.com/blog/1534147/202102/1534147-20210213110402113-221285925.png)
看到這裡細心的小夥伴發現了,這個run方法好像是順序執行的啊!
的確是的,run方法並不會實現多執行緒。而是順序執行。那麼為什麼會產生這樣的結果呢?
### 根本原因
#### 檢視run方法的原始碼
![](https://img2020.cnblogs.com/blog/1534147/202102/1534147-20210213110624643-926397578.png)
我們發現run方法只是簡單的呼叫了實現類的run。沒有進行任何的多執行緒處理。
#### 檢視start方法的原始碼
![](https://img2020.cnblogs.com/blog/1534147/202102/1534147-20210213110854555-956230486.png)
start方法就不一樣了。我們可以看到關鍵的程式碼就是start0方法。var1理解為執行緒為啟動,呼叫start0後,執行緒啟動。繼續追蹤start0.
![](https://img2020.cnblogs.com/blog/1534147/202102/1534147-20210213111100563-1653522458.png)
這個是一個使用jni的java本地方法,jvm根據不同的平臺,排程的執行緒方法不同。
借用一張網上圖,一目瞭然。
![](https://img2020.cnblogs.com/blog/1534147/202102/1534147-20210213111414257-834375847.png)
start() 方法呼叫 start0() 方法後,該執行緒並不一定會立馬執行,只是將執行緒變成了可執行狀態。具體什麼時候執行,取決於 CPU ,由 CPU 統一排程。
### 總結
Java 中實現真正的多執行緒是 start 中的 start0() 方法,run() 方法只是一個普通的