主题切换
线程状态
一、六种线程状态(Thread.State枚举)
- NEW 新建:仅创建线程对象,未调用start(),无操作系统线程
- RUNNABLE 可运行:包含就绪、运行两种细分状态,具备运行资格,等待/占用CPU
- BLOCKED 阻塞:等待synchronized同步锁,未抢到锁时进入
- WAITING 无限等待:调用wait()无超时,需其他线程notify/notifyAll唤醒
- TIMED_WAITING 计时等待:sleep、wait(long)、join(long)等带超时的等待,时间到自动恢复
- TERMINATED 终止:线程run方法执行完毕,生命周期结束
二、完整状态流转逻辑
- NEW → RUNNABLE:调用线程start()方法,创建操作系统线程进入可运行池
- RUNNABLE细分切换:就绪(有资格无CPU时间片)与运行(抢到CPU执行)互相切换
- RUNNABLE → BLOCKED:执行同步代码块时抢不到监视器锁;抢到锁后回到RUNNABLE
- RUNNABLE → WAITING:调用object.wait();其他线程notify唤醒后回到RUNNABLE
- RUNNABLE → TIMED_WAITING:Thread.sleep()、wait(超时)、join(超时);超时结束自动回到RUNNABLE
- RUNNABLE → TERMINATED:run方法全部执行完毕,线程销毁
三、面试高频问题解析
问:Java线程有哪几种状态?
答: 共六种,分别是NEW新建、RUNNABLE可运行、BLOCKED阻塞、WAITING无限等待、TIMED_WAITING计时等待、TERMINATED终止。
问:RUNNABLE为什么包含就绪和运行两种场景?
答: Java将就绪、运行统一封装为RUNNABLE状态,操作系统层面分时调度CPU,线程随时会被抢走时间片,二者切换频繁,JDK统一归为可运行状态。
问:BLOCKED和WAITING的核心区别是什么?
答: BLOCKED是等待synchronized同步锁,锁释放后自动竞争;WAITING是主动调用wait()放弃锁,必须被其他线程唤醒才能恢复运行。
问:sleep()和wait()都会进入TIMED_WAITING,二者有什么差异?
答: sleep是Thread静态方法,睡眠时不释放锁;wait是Object方法,执行时会释放当前持有的同步锁,仅能在同步代码块内调用。
问:一个线程执行完后还能再次start()吗?
答: 不能。线程进入TERMINATED终止状态后生命周期结束,再次调用start()会直接抛出IllegalThreadStateException。