new状态表示线程对象已创建但未与操作系统关联,此时isalive()为false、getid()为0;必须调用start()才能真正启动线程。

new 状态不是“线程已存在”,而是“还没跟操作系统打招呼”
你 new 一个 Thread 对象,它只是 JVM 里一个普通对象,没绑定任何 OS 线程资源。这时候调用 thread.getState() 返回 NEW,但 thread.isAlive() 是 false,thread.getId() 甚至还是 0——因为 OS 根本还不知道它。
- 常见错误:以为
new Thread(runnable)后线程就“启动了”,结果忘记调start(),runnable 逻辑压根不执行 - 实操建议:只要没调
start(),就别把它当“线程”看;调试时优先检查isAlive()而非getState() - 注意:
start()只能调一次,重复调会抛IllegalThreadStateException
Runnable 不等于“正在跑”,而是一张 CPU 入场券
RUNNABLE 是 Java 抽象出来的状态,涵盖两个真实场景:真正占用 CPU 执行(Running),和排好队等调度(Ready)。JVM 不区分这两者,但你在排查高 CPU 占用或低吞吐时,得心里有数。
- 常见现象:线程 dump 显示一堆
RUNNABLE,但业务响应慢——可能全是“排队中”,CPU 被其他线程霸占,或系统负载过高 - 参数差异:
Thread.yield()让出 CPU,但它仍处于RUNNABLE;Thread.sleep(1)则立刻进TIMED_WAITING - 性能影响:大量线程长期卡在
RUNNABLE(尤其竞争锁失败后反复重试),会加剧上下文切换开销,比直接阻塞更伤性能
Blocked / Waiting / Timed Waiting 的本质区别在“谁来唤醒”
三者表面都是“停着不动”,但触发条件和唤醒机制完全不同,混用会导致死锁或超时失效。
-
BLOCKED:只因抢不到 synchronized 锁,**必须等持有锁的线程退出同步块**才可能恢复;和 notify/wait 无关 -
WAITING:调了wait()、join()、LockSupport.park(),**必须靠notify()/notifyAll()、被 join 的线程结束、或unpark()才能出来** -
TIMED_WAITING:带时间参数的sleep()、wait(long)、join(long)、parkNanos(),**时间一到自动回RUNNABLE,无需别人唤醒** - 容易踩的坑:在 synchronized 块里调
wait()却忘了notify();或者用sleep()模拟等待锁,结果既没释放锁又白等——该用wait()的地方用了sleep()
Terminated 不是“线程没了”,而是“任务彻底交差了”
TERMINATED 表示线程的 run() 方法已自然返回(或抛出未捕获异常),OS 线程资源已被回收。但 Thread 对象本身还在堆里,可继续读 getName()、getId(),只是不能再 start()。
- 常见误解:认为
interrupt()会让线程进TERMINATED——其实它只是设个标志,线程自己决定何时响应并退出 - 实操建议:想安全终止线程,别依赖
stop()(已废弃),用 volatile 标志 + 主动检查 + 中断协作;比如while (!shutdownRequested && !Thread.currentThread().isInterrupted()) - 关键细节:线程一旦进入
TERMINATED,状态不可逆;再次调start()必抛异常,不是“重启”,而是“新建一个同名线程”
RUNNABLE 当运行中、把 WAITING 当可超时、把 TERMINATED 当对象销毁——这些认知偏差,会在 dump 分析和压测调优时悄悄放大。










