Java中多線程啟動,為什么調用的是start方法,而不是run方法?


前言

大年初二,大家新年快樂,我又開始碼字了。寫這篇文章,源於在家和基友交流的時候,基友問到了,我猛然發現還真是這么回事,多線程啟動調用的都是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的調度。

我們再使用run方法來進行調用,查看結果

public class ExtendsThread {
    public static void main(String[] args) {
        new MyThread("線程A").run();
        new MyThread("線程B").run();
        new MyThread("線程C").run();
    }
}

結果如下:

看到這里細心的小伙伴發現了,這個run方法好像是順序執行的啊!
的確是的,run方法並不會實現多線程。而是順序執行。那么為什么會產生這樣的結果呢?

根本原因

查看run方法的源代碼


我們發現run方法只是簡單的調用了實現類的run。沒有進行任何的多線程處理。

查看start方法的源碼


start方法就不一樣了。我們可以看到關鍵的代碼就是start0方法。var1理解為線程為啟動,調用start0后,線程啟動。繼續追蹤start0.

這個是一個使用jni的java本地方法,jvm根據不同的平台,調度的線程方法不同。
借用一張網上圖,一目了然。

start() 方法調用 start0() 方法后,該線程並不一定會立馬執行,只是將線程變成了可運行狀態。具體什么時候執行,取決於 CPU ,由 CPU 統一調度。

總結

Java 中實現真正的多線程是 start 中的 start0() 方法,run() 方法只是一個普通的方法。


免責聲明!

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



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