天天看点

并发(十):用一个类实现遍历线程的所有状态

在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
           

总结

  1. BLOCKED与WAITING状态的区别:
    BLOCKED状态用于等待锁的进入,WAITING状态是因为主动调用了notify、join方法,而待线程信号的通知。
  2. TIMED_WAITING与WAITING的区别:
    除了notify、join方法(有限制时间)能让线程进入TIMED_WAITING状态,sleep方法也可以,参见上例中的状态3。