用错了就翻车!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 小时前
邪修实战系列(6)
java·ide·windows·spring boot·状态模式
£漫步 云端彡3 小时前
docker常用命令
java·docker·eureka
Brookty3 小时前
【算法】滑动窗口(一)-长度最小的子数组
java·学习·算法·力扣·滑动窗口
JAVA学习通3 小时前
微服务项目->在线oj系统(Java-Spring)----6.0
java·开发语言·spring
袁煦丞 cpolar内网穿透实验室3 小时前
Remote JVM Debug远程给Java程序“做手术”!cpolar内网穿透实验室第626个成功挑战
java·开发语言·jvm·远程工作·内网穿透·cpolar
我是华为OD~HR~栗栗呀3 小时前
22届考研(华为oD)-Java面经
java·c++·后端·python·考研·华为od·华为
冻咸鱼3 小时前
LinkedList与链表
java·数据结构·链表
Yan-英杰3 小时前
Amazon SES + NestJS 实战:零成本打造高送达率邮箱验证方案
java·服务器·前端·网络·数据库·ai
青云交4 小时前
Java 大视界 -- Java 大数据机器学习模型在元宇宙虚拟场景智能交互中的关键技术
java·机器学习·边缘计算·元宇宙·多模态融合·智能交互·情感计算