← 每日面试题 学习看板

线程有几种状态,状态之间的流转是怎样的?

面试题/00java/02Java 并发编程/01线程基础概念/线程有几种状态,状态之间的流转是怎样的?.md

面试记录 2026-09-29

题目:线程有几种状态,状态之间的流转是怎样的?

难度:medium

标签:java/thread, difficulty/medium

评分:⭐⭐☆☆☆(2/5)

我的回答

线程池状态,初始态,创建中,也就是 new 的状态。然后是启动之后,等待运行中。然后正式分配 CPU 之后,是运行中 Running。然后主射了的话是 Block 主射,然后还有调等待的话是 Waiter 进行等待。然后执行完后之后应该有一个结束。

状态的转换,首先是初始态 new,然后转换调用 start,然后进入运行态 running。

我运行过程中可能出现阻塞,阻塞的话变成 black,然后阻塞恢复之后 black 再变成 running。

Running 过程中如果调用了等待进入 Water,等待唤醒之后就变回 Running,不对,应该变回准备,不是变回 Running,然后等到分配到时间片 CPU 的时候再变回 Running。

线程运行结束后,进入结束状态。

点评

优点:

不足:

补充(必背):

Java 6 种状态(Thread.State 枚举,严格按这个背):

枚举含义典型进入方式
NEW已 new 未 startnew 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 个高频考点:

  1. Java 没有 READY,Linux 有。JVM 把"就绪+运行"合并叫 RUNNABLE
  2. BLOCKED 和 WAITING 触发条件不同:BLOCKED 是抢 synchronized 锁失败(自动进入);WAITING 是显式调用 wait/join/park(不会因 CPU 调度而进入)
  3. 中断不是状态:isInterrupted() 是标志位,State 枚举里没有 INTERRUPTED

完整讲解

第一部分:知识重点剖析

核心考点定位:考察对 Thread.State 枚举的完整掌握,以及状态间转移触发的条件——尤其是"等待类"三种状态的区别。

知识点拆解:

  1. 底层原理:Thread.State 是 JDK 定义的 6 值枚举,反映 JVM 层对线程生命周期的高度抽象——刻意省略了 OS 层的 READY 状态,因为"就绪+运行"对 Java 开发者来说没有可观察差异
  2. 设计权衡:把 BLOCKED、WAITING、TIMED_WAITING 分成三种,是因为它们的唤醒机制完全不同——BLOCKED 靠抢锁自动恢复,WAITING 靠 notify/unpark,TIMED_WAITING 会自己超时
  3. 工程实践:jstack 打印线程栈时每个线程都会显示当前 State,排查死锁/线程泄漏时是核心线索

第二部分:考察方向与延伸递进

考察方向:

延伸递进面试题:

  1. BLOCKED 和 WAITING 的进入条件分别是什么?
  1. 为什么 WAITING 醒来后不是直接 Running,而是 RUNNABLE?
  1. 中断后线程状态会变吗?

第三部分:面试者参考回答(300-600 字口语化)

面试官您好,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 的带超时版本,多了"自动超时"这条退出路径。