天天看點

Java并發程式設計-線程的狀态1.五種狀态(作業系統角度)2.六種狀态(API層面)3.線程的6種狀态示範

1.五種狀态(作業系統角度)

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

Java并發程式設計-線程的狀态1.五種狀态(作業系統角度)2.六種狀态(API層面)3.線程的6種狀态示範

**[初始狀态]**僅是在語言層面建立 了線程對象, 還未與作業系統線程關聯.

[可運作狀态] (就緒狀态)指該線程已經被建立(與作業系統線程關聯), 可以由CPU排程執行

[運作狀态]

指擷取了CPU時間片運作中的狀态

當CPU時間片用完,會從[運作狀态]轉換至[可運作狀态],會導緻線程的上下文切換

如果調用了阻塞API,如BIO讀寫檔案,這時該線程實際不會用到CPU,會導緻線程上下文切換

[阻塞狀态]

等BIO操作完畢,會由作業系統喚醒阻塞的線程,轉換至[可運作狀态]

與[可運作狀态]的差別是,對[阻塞狀态]的線程來說隻要它們一-直不喚醒,排程器就-直不會考慮排程它們

[終止狀态]

表示線程已經執行完畢,生命周期已經結束,不會再轉換為其它狀态

2.六種狀态(API層面)

這是Java API層面來描述的

根據Thread State枚舉,分為六種狀态

Java并發程式設計-線程的狀态1.五種狀态(作業系統角度)2.六種狀态(API層面)3.線程的6種狀态示範
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 層面對【阻塞狀态】的細分,

BLOCKED:線程拿不到鎖,進入阻塞态,如synchronized

WAITING:當不滿足條件時,線程需要等待,如wait()方法和join()方法

TIMED_WAITING:需要等待一段時間,如sleep和帶時間參數的join()方法

後面會在狀态轉換一節詳述

TERMINATED 當線程代碼運作結束

join()函數屬于WAITING

sleep()函數屬于TIMED_WAITING

關于這兩種方法的特性可參看多線程基礎

3.線程的6種狀态示範

@Slf4j(topic = "c.Test5")
public class TestState {
    public static void main(String[] args) {
        //沒有調用線程1的start方法,是以屬于new這個狀态
        Thread t1=new Thread("t1"){
            @Override
            public void run() {
                log.debug("running...");
            }
        };
        Thread t2=new Thread("t2"){
            @Override
            public void run() {
                while(true){}   //RUNNABLE(可能分了時間片,也可能陷入IO阻塞)
            }
        };
        t2.start();
        Thread t3=new Thread("t3"){
            @Override
            public void run() {
                log.debug("running...");
            }
        };
        //t3線程start完之後就結束了,是以最終進入了terminated
        t3.start();
        Thread t4=new Thread("t4"){
            @Override
            public void run() {
                synchronized (TestState.class){
                    try {
                        //sleep的時間足夠長,主線程檢視線程狀态可以檢視到Time_Waiting
                        Thread.sleep(1000000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t4.start();
        Thread t5=new Thread("t5"){
            @Override
            public void run() {
                try{
                    //等待包含死循環的t2運作結束,是以t5會一直等待,沒有time的叫Waiting
                    t2.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        t5.start();
        Thread t6=new Thread("t6"){
            @Override
            public void run() {
                //由于t4線程已經對TestState.class上鎖了,t6拿不到鎖,就會陷入到blocked狀态
                synchronized (TestState.class){
                    try {
                        Thread.sleep(10000000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t6.start();
        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());  
    }
}
           

運作結果:

c.TestState[t3]-running
c.TestState[main]-t1 state NEW
c.TestState[main]-t2 state RUNNABLE
c.TestState[main]-t3 state TERMINATED
c.TestState[main]-t4 state TIMED_WAITING
c.TestState[main]-t5 state WAITTING
c.TestState[main]-t6 state BLOCKED