Java -- Thread中start和run方法的區別

1、認識Thread的 start() 和 run()

1。start():java

咱們先來看看API中對於該方法的介紹:安全

     使該線程開始執行;Java 虛擬機調用該線程的 run 方法。多線程

     結果是兩個線程併發地運行;當前線程(從調用返回給 start 方法)和另外一個線程(執行其 run 方法)。併發

     屢次啓動一個線程是非法的。特別是當線程已經結束執行後,不能再從新啓動。spa

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

2。run():線程

咱們仍是先看看API中對該方法的介紹:code

      若是該線程是使用獨立的 Runnable 運行對象構造的,則調用該 Runnable 對象的 run 方法;不然,該方法不執行任何操做並返回。對象

    Thread 的子類應該重寫該方法。繼承

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

3。總結:

調用start方法方可啓動線程,而run方法只是thread的一個普通方法調用,仍是在主線程裏執行。

2、代碼實例:

public static void main(String args[]) {
    Thread t = new Thread() {
        public void run() {
            pong();
        }
    };
    t.start();
    System.out.print("ping");
}
 
    static void pong() {
        System.out.print("pong");
    }

輸出結果: pingpong

public static void main(String args[]) {
    Thread t = new Thread() {
        public void run() {
            pong();
        }
    };
    t.run();
    System.out.print("ping");
}
 
    static void pong() {
        System.out.print("pong");
    }

輸出結果:pongping

經過以上兩個程序實例,能夠很容易的區分出start()方法和run()方法的區別:

t.start(); 該行代碼至關因而啓動線程,

t.run(); 該行代碼至關因而使用t這個類中的run方法而已.

3、線程狀態說明:

線程狀態從大的方面來講,可歸結爲:初始狀態、可運行狀態、不可運行狀態和消亡狀態,具體可細分爲上圖所示7個狀態,說明以下:

1)線程的實現有兩種方式,一是繼承Thread類,二是實現Runnable接口,但無論怎樣,當咱們new了thread實例後,線程就進入了初始狀態;

2)當該對象調用了start()方法,就進入可運行狀態;

3)進入可運行狀態後,當該對象被操做系統選中,得到CPU時間片就會進入運行狀態;

4)進入運行狀態後case就比較多,大體有以下情形: ﹒run()方法或main()方法結束後,線程就進入終止狀態; 當線程調用了自身的sleep()方法或其餘線程的join()方法,就會進入阻塞狀態(該狀態既停 止當前線程,但並不釋放所佔有的資源)。當

sleep()結束或join()結束後,該線程進入可運行狀態,繼續等待OS分配時間片; 當線程剛進入可運行狀態(注意,還沒運行),發現將要調用的資源被鎖牢(synchroniza,lock),將會當即進入鎖池狀態,等待獲取鎖標記(這時的鎖池裏也許已經有了其餘線

程在等待獲取鎖標記,這時它們處於隊列狀態),一旦線程得到鎖標記後,就轉入可運行狀態,等待OS分配 CPU時間片; 當線程調用wait()方法後會進入等待隊列(進入這個狀態會釋放所佔有的全部資源,與阻塞狀態不一樣),進入這個狀態後,

是不能自動喚醒的,必須依靠其餘線程調用notify()或notifyAll()方法才能被喚醒(因爲notify()只是喚醒一個線程,但咱們由不能肯定具體喚醒的是哪個線程,也許咱們須要喚醒的線程不可以被喚醒,所以在實際使用時,通常都用notifyAll()方法,喚醒

有所線程),線程被喚醒後會進入鎖池,等待獲取鎖標記。 當線程調用stop方法,便可使線程進入消亡狀態,可是因爲stop方法是不安全的,不鼓勵使用,你們能夠經過run方法裏的條件變通實現線程的 stop。

相關文章
相關標籤/搜索