1. 程式人生 > 實用技巧 >廖雪峰的多執行緒 4

廖雪峰的多執行緒 4


執行緒的狀態
在Java程式中,一個執行緒物件只能呼叫一次start()方法啟動新執行緒,並在新執行緒中執行run()方法。一旦run()方法執行完畢,執行緒就結束了。因此,Java執行緒的狀態有以下幾種:

New:新建立的執行緒,尚未執行;
Runnable:執行中的執行緒,正在執行run()方法的Java程式碼;
Blocked:執行中的執行緒,因為某些操作被阻塞而掛起;
Waiting:執行中的執行緒,因為某些操作在等待中;
Timed Waiting:執行中的執行緒,因為執行sleep()方法正在計時等待;
Terminated:執行緒已終止,因為run()方法執行完畢。

用一個狀態轉移圖表示如下:

當執行緒啟動後,它可以在Runnable、Blocked、Waiting和Timed Waiting這幾個狀態之間切換,直到最後變成Terminated狀態,執行緒終止。
執行緒終止的原因有:

執行緒正常終止:run()方法執行到return語句返回;
執行緒意外終止:run()方法因為未捕獲的異常導致執行緒終止;
對某個執行緒的Thread例項呼叫stop()方法強制終止(強烈不推薦使用)。

一個執行緒還可以等待另一個執行緒直到其執行結束。例如,main執行緒在啟動t執行緒後,可以通過t.join()等待t執行緒結束後再繼續執行:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            System.out.println("hello");
        });
        System.out.println("start");
        t.start();
        t.join();
        System.out.println("end");
    }
}

當main執行緒對執行緒物件t呼叫join()方法時,主執行緒將等待變數t表示的執行緒執行結束,即join就是指等待該執行緒結束,然後才繼續往下執行自身執行緒。所以,上述程式碼列印順序可以肯定是main執行緒先列印start,t執行緒再列印hello,main執行緒最後再列印end。

如果t執行緒已經結束,對例項t呼叫join()會立刻返回。此外,join(long)的過載方法也可以指定一個等待時間,超過等待時間後就不再繼續等待。

Java執行緒物件Thread的狀態包括:New、Runnable、Blocked、Waiting、Timed Waiting和Terminated;

通過對另一個執行緒物件呼叫join()方法可以等待其執行結束;

可以指定等待時間,超過等待時間執行緒仍然沒有結束就不再等待;

對已經執行結束的執行緒呼叫join()方法會立刻返回。