题目:线程有几种状态,状态之间的流转是怎样的?
难度:medium
标签:java/thread, difficulty/medium
评分:⭐⭐☆☆☆(2/5)
线程池状态,初始态,创建中,也就是 new 的状态。然后是启动之后,等待运行中。然后正式分配 CPU 之后,是运行中 Running。然后主射了的话是 Block 主射,然后还有调等待的话是 Waiter 进行等待。然后执行完后之后应该有一个结束。
状态的转换,首先是初始态 new,然后转换调用 start,然后进入运行态 running。
我运行过程中可能出现阻塞,阻塞的话变成 black,然后阻塞恢复之后 black 再变成 running。
Running 过程中如果调用了等待进入 Water,等待唤醒之后就变回 Running,不对,应该变回准备,不是变回 Running,然后等到分配到时间片 CPU 的时候再变回 Running。
线程运行结束后,进入结束状态。
优点:
不足:
Thread.State 里"就绪 + 运行"合并为 RUNNABLE,没有 READY 枚举补充(必背):
Java 6 种状态(Thread.State 枚举,严格按这个背):
| 枚举 | 含义 | 典型进入方式 |
|---|---|---|
NEW | 已 new 未 start | new Thread() |
RUNNABLE | 就绪 + 运行合一(JVM 无区分) | start() / 让出 CPU / 唤醒后 |
BLOCKED | 抢 synchronized 锁失败 | synchronized 竞争 |
WAITING | 无限期等待 | wait() / join() / LockSupport.park() |
TIMED_WAITING | 限期等待 | sleep(n) / wait(n) / join(n) |
TERMINATED | 已终止 | run() 返回 / 异常 |
关键流转:
NEW ──start()──▶ RUNNABLE ──▶ TERMINATED
│
├──抢锁失败──▶ BLOCKED ──抢到锁──▶ RUNNABLE
├──wait/join/park──▶ WAITING ──notify/unpark──▶ RUNNABLE
└──sleep/wait(n)──▶ TIMED_WAITING ──超时/notify──▶ RUNNABLE
3 个高频考点:
isInterrupted() 是标志位,State 枚举里没有 INTERRUPTED核心考点定位:考察对 Thread.State 枚举的完整掌握,以及状态间转移触发的条件——尤其是"等待类"三种状态的区别。
知识点拆解:
Thread.State 是 JDK 定义的 6 值枚举,反映 JVM 层对线程生命周期的高度抽象——刻意省略了 OS 层的 READY 状态,因为"就绪+运行"对 Java 开发者来说没有可观察差异jstack 打印线程栈时每个线程都会显示当前 State,排查死锁/线程泄漏时是核心线索考察方向:
monitorenter 失败 vs wait()/park())ThreadMXBean 或 jstack 打印线程状态排查线上问题延伸递进面试题:
getState() 只会返回 RUNNABLE,实际是否持有 CPU 由 OS 调度决定interrupted 标志位,State 枚举里没 INTERRUPTED;但 sleep/wait/join 被中断时会抛 InterruptedException,状态从 TIMED_WAITING/WAITING 回到 RUNNABLE面试官您好,Java 里 Thread.State 一共 6 种:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。
流转是这样的:线程 new 出来是 NEW;调用 start() 进入 RUNNABLE;如果在 RUNNABLE 里去抢 synchronized 锁失败了,就进入 BLOCKED,抢到锁再回到 RUNNABLE;如果主动调 wait()、join() 或 LockSupport.park() 就进入 WAITING,被 notify/unpark 后回到 RUNNABLE;如果是带超时的 sleep(n)、wait(n)、join(n) 就进入 TIMED_WAITING,超时或被 notify 后回到 RUNNABLE;最后 run() 结束或抛异常进入 TERMINATED。
有两个坑要特别注意:第一,Java 没有 READY 状态,OS 层的"就绪+运行"在 JVM 层都归为 RUNNABLE,所以唤醒后 getState() 直接返回 RUNNABLE,不是先"回到准备"再"进运行";第二,中断不是状态,isInterrupted() 是独立标志位,State 枚举里没有 INTERRUPTED。
BLOCKED 和 WAITING 的区别也常考:BLOCKED 是抢锁失败自动进入、靠抢锁自动恢复;WAITING 是显式调用 wait/join/park 进入、靠 notify/unpark 恢复;TIMED_WAITING 就是 wait 的带超时版本,多了"自动超时"这条退出路径。