sleep()实现强制暂停,使线程进入TIMED_WAITING状态,不占CPU且可被中断;yield()仅为礼貌让权,保持RUNNABLE状态,调度器可忽略,现代场景基本弃用。

关键看你要的是“强制暂停”还是“礼貌让权”:sleep() 是让线程真睡一会儿,yield() 只是打个招呼说“我先歇会儿”,调度器爱理不理。
需要精确等待或延时,用 Thread.sleep()
当你明确希望线程停一段时间再继续——比如限流、轮询间隔、模拟耗时操作、防止忙等——sleep() 是唯一可靠选择。
- 必须传入毫秒(或毫秒+纳秒)参数,时间一到自动恢复为就绪状态
- 线程进入 TIMED_WAITING 状态,不占用 CPU,但持有锁不变
- 可被其他线程中断,需捕获 InterruptedException
- 示例:每 500ms 检查一次网络连通性,就该写
Thread.sleep(500)
仅想提示调度器“让别人也跑跑”,考虑 Thread.yield()
yield() 不设定期限,也不保证效果,它只是向 JVM 调度器发一个软提示:“我愿意让出当前时间片”。实际是否切换,完全由调度器决定。
- 无参数,无异常,调用后线程仍处于 RUNNABLE 状态
- 常用于同优先级线程间尝试提升公平性,比如自旋等待前主动让一让
- 现代 JVM 和操作系统中效果越来越弱,多数场景下可忽略或直接删掉
- 注意:不要用它来“解决竞态条件”或“替代锁”,它不具备同步语义
别混淆它们的底层行为
sleep() 是阻塞式暂停,yield() 是非阻塞式礼让。二者都不会释放锁,这点一致;但状态变化、可中断性、可靠性完全不同。
- sleep() → 进入 TIMED_WAITING → 时间到或被中断 → 回 RUNNABLE
- yield() → 保持 RUNNABLE → 调度器可能立刻再选它 → 实际没暂停
- JVM 实现上,
Thread.sleep(0)在某些配置下会退化为 yield(),但语义仍不同
实用建议:优先用 sleep,慎用 yield
除非你在调试特定调度行为,或在极简嵌入式环境里做细粒度控制,否则 yield() 几乎没有不可替代的价值。
- 想“等 1 秒”,写
Thread.sleep(1000),别用 yield() 循环凑 - 想“避免空转消耗 CPU”,sleep(1) 比 while(true) + yield() 更合理
- 面试中被问到 yield(),重点答出“它是提示而非保证”,并说明现代场景下基本弃用

















