1. 程式人生 > >Java -- Thread中start和run方法的區別

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

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

1。start():

我們先來看看API中對於該方法的介紹:

     使該執行緒開始執行;Java 虛擬機器呼叫該執行緒的 run 方法。

     結果是兩個執行緒併發地執行;當前執行緒(從呼叫返回給 start 方法)和另一個執行緒(執行其 run 方法)。

     多次啟動一個執行緒是非法的。特別是當執行緒已經結束執行後,不能再重新啟動。

用start方法來啟動執行緒,真正實現了多執行緒執行,這時無需等待run方法體程式碼執行完畢而直接繼續執行下面的程式碼

。通過呼叫Thread類的 start()方法來啟動一個執行緒,這時此執行緒處於就緒(可執行)狀態,並沒有執行,一旦得到cpu時間片,就開始執行run()方法,這裡方法 run()稱為執行緒體,它包含了要執行的這個執行緒的內容,Run方法執行結束,此執行緒隨即終止。

2。run():

我們還是先看看API中對該方法的介紹:

      如果該執行緒是使用獨立的 Runnable 執行物件構造的,則呼叫該 Runnable 物件的 run 方法;否則,該方法不執行任何操作並返回。

    Thread

 的子類應該重寫該方法。

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

3。總結:

呼叫start方法方可啟動執行緒,而run方法只是thread的一個普通方法呼叫,還是在主執行緒裡執行。

二、程式碼例項:

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方法而已.

三、執行緒狀態說明:

執行緒狀態從大的方面來說,可歸結為:初始狀態、可執行狀態、不可執行狀態和消亡狀態,具體可細分為上圖所示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方法裡的條件變通實