面试知识库
基础

线程生命周期与状态转换#

一句话答案#

6 种状态:NEW→RUNNABLE→(BLOCKED/WAITING/TIMED_WAITING)→TERMINATED,start() 启动,run() 结束后终止。

核心要点

状态转换:

  • NEW → RUNNABLE:start()
  • RUNNABLE → BLOCKED:等待synchronized
  • RUNNABLE → WAITING:wait()/join()/LockSupport.park()
  • RUNNABLE → TIMED_WAITING:sleep()/wait(timeout)
  • → TERMINATED:run()结束
面试回答(2分钟版)

Java 线程在其生命周期中有六种状态。NEW 是线程刚创建还没调用 start 的初始状态;调用 start 后进入 RUNNABLE,表示可运行或正在运行;当线程尝试获取 synchronized 锁失败时进入 BLOCKED 状态,等待锁释放;调用 wait、join 或 LockSupport.park 后进入 WAITING,需要被其他线程显式唤醒;调用 sleep 或带超时参数的 wait 进入 TIMED_WAITING,到时间自动恢复;run 方法执行完毕后进入 TERMINATED 终止状态。最容易混淆的是 BLOCKED 和 WAITING 的区别:BLOCKED 是被动的,线程想进同步块但锁被别人持有所以进不去;WAITING 是主动的,线程已经进了同步块但主动放弃执行权等待通知。另外需要注意 Thread.stop 已经被废弃,正确停止线程应该用 interrupt 配合标志位的协作式中断。

追问与易错

追问方向:

  • “BLOCKED 和 WAITING 的区别?”→ BLOCKED 是被动等锁(想进 synchronized 但锁被占),WAITING 是主动等通知(已持锁但调了 wait/join/park 主动放弃执行权)
  • “interrupt() 能中断什么状态的线程?”→ WAITING/TIMED_WAITING 状态的线程会抛 InterruptedException 被唤醒;RUNNABLE 状态只设置中断标志位需要代码主动检查;BLOCKED 状态不响应中断
  • “守护线程和用户线程的区别?”→ JVM 在所有用户线程结束后退出,不等守护线程;GC 线程就是典型守护线程。通过 setDaemon(true) 设置,必须在 start() 前调用

易错点:

  • ❌ 混淆 BLOCKED 和 WAITING
  • ❌ Thread.stop() 可以停止线程——已废弃