五種狀態
這是從操作系統層面來描述的。
新建狀態
:僅是在語言層面創建了線程對象,還未與操作系統線程關聯可運行狀態(就緒狀態)
:指該線程已經被創建(與操作系統線程關聯),可以由 CPU 調度執行運行狀態
:指獲取了 CPU 時間片運行中的狀態 當 CPU 時間片用完,會從運行狀態轉換至可運行狀態,會導致線程的上下文切換阻塞狀態
:如果調用了阻塞 API,如 BIO 讀寫文件,這時該線程實際不會用到 CPU,會導致線程上下文切換,進入阻塞狀態等 BIO 操作完畢,會由操作系統喚醒阻塞的線程,轉換至可運行狀態。與可運行狀態的區別是,對阻塞狀態的線程來說只要它們一直不喚醒,調度器就一直不會考慮調度它們終止狀態(死亡狀態)
:表示線程已經執行完畢,生命週期已經結束,不會再轉換爲其它狀態
六種狀態
這是從 Java API 層面來描述的 根據 Thread.State 枚舉,分爲六種狀態
NEW
線程剛被創建,但是還沒有調用 start() 方法RUNNABLE
是調用了 start() 方法之後,注意,Java API 層面的 RUNNABLE 狀態涵蓋了 操作系統 層面的 【可運行狀態】、【運行狀態】和【阻塞狀態】(由於 BIO 導致的線程阻塞,在 Java 裏無法區分,仍然認爲 是可運行)BLOCKED
,WAITING
,TIMED_WAITING
都是 Java API 層面對【阻塞狀態】的細分TERMINATED
當線程代碼運行結束
例如:
@Slf4j(topic = "c.TestState")
public class TestState {
public static void main(String[] args) throws IOException {
// New
Thread t1 = new Thread("t1") {
@Override
public void run() {
log.debug("running...");
}
};
// Runnable
Thread t2 = new Thread("t2") {
@Override
public void run() {
while(true) {
}
}
};
t2.start();
// Terminated
Thread t3 = new Thread("t3") {
@Override
public void run() {
log.debug("running...");
}
};
t3.start();
// Timed_waiting
Thread t4 = new Thread("t4") {
@Override
public void run() {
// 這裏t4先對對象上鎖,t6線程就沒辦法加鎖了,會陷入 blocked 狀態
synchronized (TestState.class) {
try {
Thread.sleep(1000000); // timed_waiting
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t4.start();
// Waiting
Thread t5 = new Thread("t5") {
@Override
public void run() {
try {
t2.join(); // waiting
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t5.start();
// Blocked
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();
}
}
/*Output:
18:02:11.284 c.TestState [t3] - running...
18:02:11.784 c.TestState [main] - t1 state NEW
18:02:11.784 c.TestState [main] - t2 state RUNNABLE
18:02:11.784 c.TestState [main] - t3 state TERMINATED
18:02:11.784 c.TestState [main] - t4 state TIMED_WAITING
18:02:11.784 c.TestState [main] - t5 state WAITING
18:02:11.784 c.TestState [main] - t6 state BLOCKED
*/