Java並行(十一)----執行緒五種狀態與六種狀態

2023-06-15 21:00:44

1、五種狀態

這是從 作業系統 層面來描述的

  • 【初始狀態】僅是在語言層面建立了執行緒物件,還未與作業系統執行緒關聯

  • 【可執行狀態】(就緒狀態)指該執行緒已經被建立(與作業系統執行緒關聯),可以由 CPU 排程執行

  • 【執行狀態】指獲取了 CPU 時間片執行中的狀態

    • 當 CPU 時間片用完,會從【執行狀態】轉換至【可執行狀態】,會導致執行緒的上下文切換

  • 【阻塞狀態】

    • 如果呼叫了阻塞 API,如 BIO 讀寫檔案,這時該執行緒實際不會用到 CPU,會導致執行緒上下文切換,進入【阻塞狀態】

    • 等 BIO 操作完畢,會由作業系統喚醒阻塞的執行緒,轉換至【可執行狀態】

    • 與【可執行狀態】的區別是,對【阻塞狀態】的執行緒來說只要它們一直不喚醒,排程器就一直不會考慮排程它們

  • 【終止狀態】表示執行緒已經執行完畢,生命週期已經結束,不會再轉換為其它狀態

2、六種狀態

這是從 Java API 層面來描述的,根據 Thread.State 列舉,分為六種狀態

  • NEW 執行緒剛被建立,但是還沒有呼叫 start() 方法

  • RUNNABLE (RUNNING)當呼叫了 start() 方法之後,注意,Java API 層面的 RUNNABLE 狀態涵蓋了 作業系統 層面的【可執行狀態】、【執行狀態】和【阻塞狀態】(由於 BIO 導致的執行緒阻塞,在 Java 裡無法區分,仍然認為是可執行)

  • BLOCKEDWAITINGTIMED_WAITING 都是 Java API 層面對【阻塞狀態】的細分,後面會在狀態轉換一節詳述

  • TERMINATED 當執行緒程式碼執行結束

程式碼範例

@Slf4j(topic = "c.TestState")
public class TestState {
    public static void main(String[] args) throws IOException {
        Thread t1 = new Thread("t1") {
            @Override
            public void run() {
                log.debug("running...");
            }
        };  // 未start  所以紀錄檔未列印
​
        Thread t2 = new Thread("t2") {
            @Override
            public void run() {
                while(true) { // runnable
​
                }
            }
        };
        t2.start();
​
        Thread t3 = new Thread("t3") {
            @Override
            public void run() {
                log.debug("running...");
            }
        };
        t3.start();
​
        Thread t4 = new Thread("t4") {
            @Override
            public void run() {
                synchronized (TestState.class) {
                    try {
                        Thread.sleep(1000000); // timed_waiting
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t4.start();
​
        Thread t5 = new Thread("t5") {
            @Override
            public void run() {
                try {
                    t2.join(); // waiting
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        t5.start();
​
        Thread t6 = new Thread("t6") {
            @Override
            public void run() {
                synchronized (TestState.class) { // blocked
                    try {
                        Thread.sleep(1000000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t6.start();
​
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.debug("t1 state {}", t1.getState());
        log.debug("t2 state {}", t2.getState());
        log.debug("t3 state {}", t3.getState());
        log.debug("t4 state {}", t4.getState());
        log.debug("t5 state {}", t5.getState());
        log.debug("t6 state {}", t6.getState());
        System.in.read();
    }
}

輸出