操作系统
从 操作系统 层面来描述的
- 【初始状态】仅是在语言层面创建了线程对象,还未与操作系统线程关联
- 【可运行状态】(就绪状态)指该线程已经被创建(与操作系统线程关联),可以由 CPU 调度执行
- 【运行状态】指获取了 CPU 时间片运行中的状态
- 当 CPU 时间片用完,会从【运行状态】转换至【可运行状态】,会导致线程的上下文切换
- 【阻塞状态】
- 如果调用了阻塞 API,如 BIO 读写文件,这时该线程实际不会用到 CPU,会导致线程上下文切换,进入【阻塞状态】
- 等 BIO 操作完毕,会由操作系统唤醒阻塞的线程,转换至【可运行状态】
- 与【可运行状态】的区别是,对【阻塞状态】的线程来说只要它们一直不唤醒,调度器就一直不会考虑调度它们
【终止状态】表示线程已经执行完毕,生命周期已经结束,不会再转换为其它状态
Java API
从 Java API 层面来描述的

NEW线程刚被创建,但是还没有调用 start() 方法
- RUNNABLE 当调用了 start() 方法之后,注意,Java API 层面的 RUNNABLE 状态涵盖了 操作系统 层面的
- 【可运行状态】、【运行状态】和【阻塞状态】(由于 BIO 导致的线程阻塞,在 Java 里无法区分,仍然认为是可运行 RUNNING)
- BLOCKED , WAITING , TIMED_WAITING 都是 Java API 层面对【阻塞状态】的细分,后面会在状态转换一节详述
- TERMINATED 当线程代码运行结束
- 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
- 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。 - 阻塞(BLOCKED):表示线程阻塞于锁。
- 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
- 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
- 终止(TERMINATED):表示该线程已经执行完毕。
线程的状态图
```java
package cn.itcast.n3;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j(topic = “c.TestState”) public class TestState { public static void main(String[] args) throws IOException { // t1线程没有调用start方法,所以线程状态是NEW Thread t1 = new Thread(“t1”) { @Override public void run() { log.debug(“running…”); } };
// t2线程陷入死循环,一直处于运行,分到了时间片,或者没有分到时间片,陷入了CPU的IO阻塞,这些情况都属于RUNNABLEThread t2 = new Thread("t2") {@Overridepublic void run() {while(true) { // runnable}}};t2.start();// t3线程顺利执行完毕,该线程的状态是TERMINATEDThread t3 = new Thread("t3") {@Overridepublic void run() {log.debug("running...");}};t3.start();// t4线程等待睡眠,线程的状态变为TIMED_WAITINGThread t4 = new Thread("t4") {@Overridepublic void run() {synchronized (TestState.class) {try {Thread.sleep(1000000); // timed_waiting} catch (InterruptedException e) {e.printStackTrace();}}}};t4.start();// t5线程调用t2线程,等待t2线程运行结束,就会导致t5一直等待,因为没有加时限,不会被CPU任务调度,该线程状态是WAITINGThread t5 = new Thread("t5") {@Overridepublic void run() {try {t2.join(); // waiting} catch (InterruptedException e) {e.printStackTrace();}}};t5.start();// t6线程加了锁,而t4线程先进行了加锁,所以t6拿不到这个对象的锁,最后被阻塞住了,状态是BLOCKEDThread t6 = new Thread("t6") {@Overridepublic void run() {synchronized (TestState.class) { // blockedtry {Thread.sleep(1000000);} catch (InterruptedException e) {e.printStackTrace();}}}};t6.start();try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}log.debug("t1 state {}", t1.getState());log.debug("t2 state {}", t2.getState());log.debug("t3 state {}", t3.getState());log.debug("t4 state {}", t4.getState());log.debug("t5 state {}", t5.getState());log.debug("t6 state {}", t6.getState());System.in.read();}
} ```
