java中線程的6中狀態

1.背景

編寫多線程相關的程序,必然會用到線程狀態的相關知識點,

那麼這篇博客就給大家系統的分析一下多線程的狀態,

由於java中線程狀態與操作系統中的線程狀態劃分有區別,

因此這裏優先介紹操作系統的5種線程狀態

2.操作系統給線程劃分的5種狀態

 狀態說明:

狀態一:【初始狀態】僅是在語言層面創建了線程對象,還未與操作系統線程關聯

狀態二:【可運行狀態(就緒狀態)】指該線程已經被創建(與操作系統線程關聯),可以由 CPU 調度執行

狀態三:【運行狀態】指獲取了 CPU 時間片運行中的狀態當 CPU 時間片用完,會從【運行狀態】轉換至【可運行狀態】,會導致線程的上下文切換,因此並不是線程越多越好.

狀態四:【阻塞狀態】如果調用了阻塞 API,如 BIO 讀寫文件,這時該線程實際不會用到 CPU,會導致線程上下文切換,進入【阻塞狀態】等 BIO 操作完畢,會由操作系統喚醒阻塞的線程,轉換至【可運行狀態】與【可運行狀態】的區別是,對【阻塞狀態】的線程來說只要它們一直不喚醒,調度器就一直不會考慮調度它們

狀態五:【終止狀態】表示線程已經執行完畢,生命週期已經結束,不會再轉換爲其它狀態

3.java中給線程劃分的6中狀態

java中規定線程有6中狀態

源碼: Thread.State 中,如下:

public enum State {
        NEW,
        RUNNABLE,
        BLOCKED,
        WAITING,
        TIMED_WAITING,
        TERMINATED;
    }

 

 狀態說明:

NEW: 線程剛被創建,但是還沒有調用 start() 方法
RUNNABLE:當調用了 start() 方法之後,注意,Java API 層面的 RUNNABLE 狀態涵蓋了 操作系統 層面的【可運行狀態】、【運行狀態】和【阻塞狀態】(由於 BIO 導致的線程阻塞,在 Java 裏無法區分,仍然認爲是可運行)
BLOCKED 、WAITING 、TIMED_WAITING : 都是 Java API 層面對【阻塞狀態】的細分,請看下面的狀態案例演示。
TERMINATED:當線程代碼運行結束

4.代碼演示java中的5種狀態

package com.ldp.demo01;

import com.common.MyThreadUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author 姿勢帝-博客園
 * @address https://www.cnblogs.com/newAndHui/
 * @WeChat 851298348
 * @create 01/16 6:38
 * @description
 */
@Slf4j
public class ThreadStateTest {
    /**
     * java 中線程的6中狀態演示
     *
     * @param args
     */
    public static void main(String[] args) {
        // 演示 NEW 狀態
        Thread thread1 = new Thread(() -> {
        }, "thread1");

        // 演示 RUNNABLE 狀態
        Thread thread2 = new Thread(() -> {
            while (true) {
            }
        }, "thread2");
        thread2.start();

        // 演示 TERMINATED 狀態
        Thread thread3 = new Thread(() -> {
            log.debug("running........");
        }, "thread3");
        thread3.start();

        // 演示 TIMED_WAITING 狀態
        Thread thread4 = new Thread(() -> {
            synchronized (ThreadStateTest.class) {
                MyThreadUtil.sleep(10000);
            }
        }, "thread4");
        thread4.start();

        // 演示 WAITING 狀態
        Thread thread5 = new Thread(() -> {
            try {
                thread2.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread5");
        thread5.start();

        // 演示 BLOCKED 狀態
        Thread thread6 = new Thread(() -> {
            synchronized (ThreadStateTest.class) {
                MyThreadUtil.sleep(10000);
            }
        }, "thread6");
        thread6.start();
        // 等2秒 後查看狀態
        MyThreadUtil.sleep(2);

        log.debug("thread1 state = {}", thread1.getState()); //  NEW
        log.debug("thread2 state = {}", thread2.getState()); //  RUNNABLE
        log.debug("thread3 state = {}", thread3.getState()); //  TERMINATED
        log.debug("thread4 state = {}", thread4.getState()); //  TIMED_WAITING
        log.debug("thread5 state = {}", thread5.getState()); //  WAITING
        log.debug("thread6 state = {}", thread6.getState()); //  BLOCKED
    }
}

 

測試結果:

21:08:29 [thread3] DEBUG com.ldp.demo01.ThreadStateTest.33 -> running........
21:08:31 [main] DEBUG com.ldp.demo01.ThreadStateTest.65 -> thread1 state = NEW
21:08:31 [main] DEBUG com.ldp.demo01.ThreadStateTest.66 -> thread2 state = RUNNABLE
21:08:31 [main] DEBUG com.ldp.demo01.ThreadStateTest.67 -> thread3 state = TERMINATED
21:08:31 [main] DEBUG com.ldp.demo01.ThreadStateTest.68 -> thread4 state = TIMED_WAITING
21:08:31 [main] DEBUG com.ldp.demo01.ThreadStateTest.69 -> thread5 state = WAITING
21:08:31 [main] DEBUG com.ldp.demo01.ThreadStateTest.70 -> thread6 state = BLOCKED

5.區別

完美!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章