Java线程状态

java线程状态详解



进程三态模型

操作系统中有比较经典的进程三态模型, 各状态之间的转换关系如下图:

进程三态模型


Java线程状态

java.long.Thread中有个内部的枚举类State用来表示线程的状态, 它的定义如下:

public enum State {
    NEW,      // 刚创建, 还没启动
    RUNNABLE, // 可运行状态
    BLOCKED,  // 阻塞态, 或被挂起
    WAITING,  // 等待锁的状态
    TIMED_WAITING, // 等待时间的状态, 如sleep就在等待时间
    TERMINATED;  // 终止态
    }

线程状态解释

  • NEW: 线程还没被start()启动. 调用了start()状态也不一定会立即改变, 中间还有一些步骤.
  • RUNNABLE: NEW状态的线程start()结束后会进入RUNNABLE状态. 正在运行的线程一定处于RUNNABLE状态, 使用Thread.currentThread().getState()只会得到RUNNABLE. 处于RUNNABLE状态的线程并不一定在运行. 比如当线程发生了yield()操作时, 该线程仍然是RUNNABLE状态, 要是对应到操作系统中的三态模型就该算是就绪了; 再比如, 在BIO中, 线程正在网络等待时, 现成的状态仍然时RUNNABLE, 而在底层实际上已经被阻塞了.
  • BLOCKED: 阻塞态, 原因通常是在等待某个, 当某个synchronized正好有线程正在使用, 另一个线程尝试进入该临界区的时候就会被阻塞. 得到锁(比如另一个线程走完了临界区或发生了相应锁对象的wait()操作)之后状态会由BLOCKED恢复到RUNNABLE.
  • WAITING: 这种状态通常是调用某个锁对象wait()方法的结果, 类似的有Thread.join(). 跟BLOCKED不同, BLOCKED是表示不能进入临界区, 所以在等待; WAITING是已经进入了临界区, 或者可理解为已经在运行了, 然后发现缺少某些资源(锁对象), 放弃运行权, 等待资源准备好. 对某个锁对象notify()时, 将从等待池中唤醒一个WAITING状态的线程恢复到RUNNABLE状态
  • TIMED_WAITING: 跟WAITING不一样的地方是, WAITING等待锁对象,它等待的是时间, 比如使用Thread.sleep()相当于把时间资源作为所对象. 时间到达时触发线程回到工作状态.
  • TERMINATED: 线程结束了,run()方法跑完了. 这是Java的一种状态,在操作系统内部可能线程已经注销了.

状态转换图

进程三态模型