用错了就翻车!Thread.sleep() vs Thread.yield() 的区别,很多人都踩过坑

原文来自于:zha-ge.cn/java/88

用错了就翻车!Thread.sleep() vs Thread.yield() 的区别,很多人都踩过坑

其实我当初刚写多线程的时候,真不是很懂 Thread.sleepThread.yield。一堆人跟我说"你多线程慢了就 sleep ,想礼让就 yield!",结果一搞项目翻车了。血的教训啊,今天来叨叨下到底这俩有啥门道,别踩我踩过的坑!


有一次领导让我写个限速的小功能,意思是并发快了就歇一会,别把 Redis 打爆,好家伙,我脑子一热就写个 sleep:

java 复制代码
while (!queue.isEmpty()) {
    process(queue.poll());
    Thread.sleep(10); // 休息下,别太快......
}

用起来咋感觉还不错?起码我本地压根没问题。可是部署到测试环境一跑,QA直接就问:哥们,你这线程干嘛罢工啊?CPU 一点都没起来,感觉像养老了。

Thread.sleep,真的只是睡觉

说白了,Thread.sleep(mx) 就是真让线程睡觉------你指定多少毫秒,它就"假死"多少毫秒。CPU 直接腾出来了,线程啥事也不管,闹钟响才迷迷糊糊爬起来接着干活。

这也太 literal(字面意思)了吧?但"灵活"真的不是它的长项。你要是 sleep 一长,线程和 CPU 就硬生生等你醒。你要随时被打断,还得自己写:

java 复制代码
try {
    Thread.sleep(10);
} catch (InterruptedException e) {
    // 别装死,赶紧收拾跑路啥的
}

再瞧瞧 Thread.yield,那就真是个性子

yield() 就比较像高铁上抢厕所,你发现后面一堆人排队,自己赶紧出来把机会给别人。它对调度器说:"我现在不急,让一下先。" 然而纯"礼让"好像天真了点。调度器接不接受,全凭它心情。有时候你礼让了半天还是你继续上,尴尬不?

比如下面代码,看着优雅,其实有时候毫无卵用:

java 复制代码
while (workRemain()) {
    if (shouldYield()) {
        Thread.yield();
    }
    doWork();
}

但操作系统看心情能不能换人,你 yield 十遍,没准还是你自己,不保证真的"止住"高压力线程。


踩坑瞬间

说个真实故事,我和同事曾经在抢锁环节用 yield() 替代了 sleep(),图啥好看......理想情况是线程能频繁让出时间片,别死磕。现实中,生产环境直接 CPU 飙红,线程数激增,系统卡爆。为啥?因为 yield() 压根不保证你真让得出去,结果线程忙着自嗨,啥活也没干,全在争调度。

再有一次,反着来,把 sleep(0)yield() 用,想着只让一步,实际是让整个时间片,线程直接处于"睡懒觉"状态,响应慢了好几倍,被 PM 追着问咋回事。


经验启示

我自己薅头发总结了一下,这俩经典用法别整错:

  • Thread.sleep(n):
    • 想真暂停/限速,一定用它,准确可控,但别懒得捕获 InterruptedException。
    • 注意别乱用小数值疯狂 sleep,浪费调度次数,CPU 其实悲伤。
  • Thread.yield():
    • 只建议在极特殊情况下临时"礼让",比如写协作算法模拟"自旋",不要求马上效果。
    • 千万别图省事指望 yield 能帮你防止高 CPU,实话说它调度不"靠谱"。
场景 推荐方法 备注
限速/节流 Thread.sleep 必须暂停就 sleep,别全指望 yield
协作式算法/自旋 Thread.yield 礼让不一定生效,慎用

有时候你会觉得多线程很玄乎,工具箱里啥花样都有,真用错一下,集群"嘎"的一下就躺那儿了......所以千万别被名词带得"云里雾里"。

写在最后

反正写线程的事,大家都喜欢糊弄两句,但是真遇上坑,才会理解"语文理解能力"也是代码能力。以后记得:sleep 就是真的睡觉,yield 基本算个"嘴上客气",千万别在关键地方搞混。这种小细节,才是写多线程的下饭小知识! 你有没有被 sleep/yield 坑过?欢迎留言嘲笑一下我,哈哈哈!

相关推荐
野生技术架构师3 分钟前
牛客网Java 高频面试题总结(2025最新版)
java·开发语言·面试
纪莫12 分钟前
技术面:SpringBoot(springboot的类加载和传统的双亲委派有什么区别、如何按顺序实例化Bean)
java·spring·java面试⑧股
kyle~30 分钟前
CPU调度---协程
java·linux·服务器·数据库·c++20
会飞的小蛮猪34 分钟前
Skywalking运维之路(Skywalking服务搭建)
java·运维·监控
L.EscaRC43 分钟前
Redisson在Spring Boot中的高并发应用解析
java·spring boot·后端
他们叫我技术总监1 小时前
从开发者视角深度评测:ModelEngine 与 AI 开发平台的技术博弈
java·人工智能·dubbo·智能体·modelengine
李辉20031 小时前
Python逻辑运算符
java·网络·python
摇滚侠1 小时前
Spring Boot3零基础教程,StreamAPI 介绍,笔记98
java·spring boot·笔记
扫地僧过江南1 小时前
Kanass零基础学习,如何进行任务管理
java·禅道·项目管理工具
无敌最俊朗@1 小时前
C++ 值类别与移动语义详解(精简版)
java·数据结构·算法