timed_waiting 是 waiting 的扩展,增加了内核级定时器自动唤醒机制;waiting 依赖 notify/interrupt 等外部信号,而 timed_waiting 还支持超时后由 os 自动唤醒,不耗 cpu 且更可控。

因为 TIMED_WAITING 的本质,就是 WAITING 加上一个内核级定时器触发的自动唤醒机制。
核心区别在于“是否依赖外部信号”
WAITING 状态的线程完全被动:它必须等另一个线程调用 notify()、notifyAll()、interrupt() 或目标线程自然结束(如 join),才能离开等待队列。没有这些动作,它就永远卡住。
TIMED_WAITING 也接受上述唤醒方式,但额外内置了一条“逃生通道”——操作系统内核维护的超时计时器。一旦设定的时间到达,内核会主动将该线程从等待队列中移出,并将其状态切回 RUNNABLE,无需任何 Java 层代码干预。
这个“时间觉醒窗”由 JVM 和 OS 共同保障
你写的 Thread.sleep(3000) 或 wait(5000) 并不是在 Java 层轮询倒计时,而是:
- JVM 向操作系统发起系统调用(如 Linux 的 nanosleep 或 epoll_wait 带 timeout)
- OS 将线程挂起,并注册一个高精度定时器事件
- 超时时刻一到,OS 自动将线程标记为“就绪”,放入调度队列
- JVM 检测到该信号后,恢复线程执行并抛出或返回
它不是“忙等”,也不是“Java 层模拟”
有人误以为 sleep 是 JVM 自己 while 循环加 System.nanoTime() 判断,这是错的。真实情况是:
- 线程在 TIMED_WAITING 期间不消耗 CPU 时间片
- 不会出现在 top 或 jstack 中的 RUNNABLE 列表里
- 线程栈显示 java.lang.Thread.State: TIMED_WAITING (sleeping) 或 (on object monitor),说明控制权已交还给 OS
- 即使应用层无任何 notify/interrupt,只要物理时间走完,线程必定醒来
所以“多了一个物理时间觉醒窗”,准确说是多了一种确定性的、OS 级别的唤醒源
WAITING 只有“别人叫你”这一种唤醒方式;TIMED_WAITING 则有“别人叫你”或“时间到了你自己醒”两种方式。后者不依赖协作线程的逻辑正确性,因此更可控、更可预测,也更适合做容错与超时保护。











