在Thread中,有一個關于線程狀态的枚舉類Thread.State,其共有六個狀态,分别為:
1. NEW, 線程未啟動;
2. RUNNABLE,線程正在運作中;
3. BLOCKED, 線程因為等待鎖被阻塞;
4. WAITING,線程處于等待(信号)狀态中;
5. TIMED_WAITING,主動調用了限時等待方法而處于等待狀态中;
6. TERMINATED,線程已結束;
下面我們用一個類來周遊線程的所有狀态:
public class ThreadStateTest extends Thread {
// 同步鎖1
private static Object monitorA = new Object();
// 同步鎖2
private static Object monitorB = new Object();
// 進入條件
private static volatile boolean locked = false;
public void run() {
// 一旦啟動,将會進入RUNNABLE狀态
System.out.println("2:" + this.getState());
synchronized (monitorA) {
try {
// 3:此時探測,将會處于TIMED_WAITING狀态
Thread.sleep();
//4:等待鎖,處于BLOCKED狀态;
synchronized (monitorB) {
while(!locked) {
// 5: 等待信号,處于WAITING狀态
monitorB.wait();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread th = new ThreadStateTest();
// 未啟動,NEW狀态
System.out.println("1: " + th.getState());
th.start();
// 啟動額外的線程,用于觀測線程的狀态變化
new Thread() {
public void run() {
synchronized (monitorB) {
System.out.println("3:" + th.getState());
while(th.getState() != Thread.State.BLOCKED) {
Thread.yield();
}
System.out.println("4:" + th.getState());
}
while(th.getState() != Thread.State.WAITING) {
Thread.yield();
}
System.out.println("5:" + th.getState());
// 發信号通知線程激活
synchronized (monitorB) {
locked = true;
monitorB.notify();
}
}
}.start();
// 等待線程結束,擷取線程的終結狀态
th.join();
System.out.println("6:" + th.getState());
}
}
最後的輸入結果如下,六個狀态一個不少:
: NEW
:RUNNABLE
:TIMED_WAITING
:BLOCKED
:WAITING
:TERMINATED
總結
- BLOCKED與WAITING狀态的差別:
BLOCKED狀态用于等待鎖的進入,WAITING狀态是因為主動調用了notify、join方法,而待線程信号的通知。
- TIMED_WAITING與WAITING的差別:
除了notify、join方法(有限制時間)能讓線程進入TIMED_WAITING狀态,sleep方法也可以,參見上例中的狀态3。