在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。