Java的每个线程都具备本人的状态,Thread类中成员变量threadStatus存储了线程的状态:

private volatile int threadStatus = 0;

在Thread类中也定义了状态的枚举,共六种,如下:

public enum State {    NEW,            //    新建状态    RUNNABLE,        //    执行状态    BLOCKED,        //    阻塞状态    WAITING,        //    无限期期待状态    TIMED_WAITING,  //  有限期期待状态    TERMINATED;     //  退出状态}

threadStatus初始值为0,对应的就是NEW状态。

  • NEW:新建状态,new Thread()时处于这个状态,此时线程还未开始执行
  • RUNNABLE:执行状态,当调用了start办法后,线程处于此状态,当然此刻CPU不肯定正在执行它
  • BLOCKED:阻塞状态,线程期待锁时处于此状态
  • WAITING:无限期期待状态,须要被唤醒的期待属于此状态,如Object.wait
  • TIMED_WAITING:有限期期待状态,调用一些有超时工夫的期待办法会进入此状态,如Thread.sleep、Object.wait、Thread.join、Lock.tryLock、Condition.await
  • TERMINATED:退出状态,可能是失常运行结束,也可能是抛出了异样导致线程终止

咱们能够通过getState获取线程的状态:

State state = thread.getState();

接下来,咱们通过示例来感触线程状态的变动。

示例一:

Thread t = new Thread(() -> {    System.out.println("sleep");    //    休眠2秒    ThreadUtil.sleep(2000);    System.out.println("run");});//    启动前先打印一下线程状态System.out.println(t.getState());//    启动线程t.start();//    启动后立刻打印一次线程状态System.out.println(t.getState());//    每隔500毫秒打印一次线程状态while (true) {    ThreadUtil.sleep(500);    System.out.println(t.getState());}

输入:

NEWRUNNABLEsleepTIMED_WAITINGTIMED_WAITINGTIMED_WAITINGrunTERMINATEDTERMINATEDTERMINATEDTERMINATEDTERMINATEDTERMINATEDTERMINATED

能够看出,线程创立后,初始状态为NEW;
调用start办法后状态变更为了RUNNABLE;
当线程内执行了sleep,休眠2秒钟,状态变更为了TIMED_WAITING;
当线程执行实现后,状态变更为了TERMINATED。

示例二:
本示例演示在多线程争抢锁的状况下,线程状态的变动。

private static Object lock = new Object();public static void main(String[] args) {    Runnable runnable = () -> {        //    加锁        synchronized (lock) {            System.out.println(Thread.currentThread().getName() + " lock");            ThreadUtil.sleep(2000);        }        System.out.println(Thread.currentThread().getName() + " exit");    };    Thread t1 = new Thread(runnable, "t1");    Thread t2 = new Thread(runnable, "t2");    t1.start();    t2.start();    while (true) {        ThreadUtil.sleep(500);        System.out.println(t1.getName() + ":" + t1.getState());        System.out.println(t2.getName() + ":" + t2.getState());    }}

输入:

t1 lock                t1取得了锁t1:TIMED_WAITING    t1 sleep,进入无限期待状态t2:BLOCKED          t2未取得锁,因而进入阻塞状态t1:TIMED_WAITING    t2:BLOCKEDt1:TIMED_WAITINGt2:BLOCKEDt1 exit             t1开释锁,执行实现,退出t2 lock             t2取得锁t1:TERMINATED       t1曾经是退出状态t2:TIMED_WAITING    t2 sleep,进入无限期待状态t1:TERMINATED       t2:TIMED_WAITINGt1:TERMINATEDt2:TIMED_WAITINGt1:TERMINATEDt2:TIMED_WAITINGt2 exit            t2开释锁,执行实现,退出t1:TERMINATED      t1为退出状态t2:TERMINATED      t2为退出状态

示例三:
本示例演示了线程如何进入和退出WAITING状态。

private static Object obj = new Object();public static void main(String[] args) {    Runnable runnable = () -> {        synchronized (obj) {            try {                //    期待                obj.wait();            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println("exit");        }    };    Thread t1 = new Thread(runnable, "t1");    System.out.println(t1.getName() + ":" + t1.getState());    t1.start();    System.out.println(t1.getName() + ":" + t1.getState());    for (int i = 0; i < 20; i++) {        ThreadUtil.sleep(500);        if(i == 3) {            synchronized (obj) {                //    唤醒                obj.notify();            }        }        System.out.println(t1.getName() + ":" + t1.getState());    }}

输入:

t1:NEWt1:RUNNABLEt1:WAITING    调用了obj.wait()进入有限期待状态t1:WAITINGt1:WAITINGt1:BLOCKED  主线程取得锁,进行notify,t1进入了阻塞状态exit               t1线程退出同步块,执行实现t1:TERMINATED  t1线程退出t1:TERMINATED

Java Thread的threadStatus字段值的更新代码位于hotspot c++源码中,JDK源码中看不到。
Java的线程状态并非是操作系统的理论线程状态,但与操作系统的线程状态是有对应关系的,后续有须要深入分析操作系统原理、hotspot源码再开展。