网易首页 > 网易号 > 正文 申请入驻

线程只等了 1 秒,整个池子为什么全堵住了?

0
分享至

一个「只等 1 秒」的动作,怎么就把池子堵死了病根:这 1 秒里,线程在占着工位发呆JDK 9 塞给我们一个「定时闹钟」闹钟背后是谁在计时同一场实验,两种写法跑出来的差距能直接抄进项目的重试工具进阶一档:指数退避只改一个地方五个最容易踩的坑

线上有个接口偶尔超时,翻代码会发现里面写了段重试:调用第三方失败,就等 1 秒再试一次。看起来人畜无害——不就是等 1 秒吗。可正是这 1 秒,在并发一上来之后,能把整个线程池拖进泥里。

先把那段代码摆出来,它太常见了:



假设线程池里一共 4 个线程,同时来了 4 个请求,全都赶上支付方抖动失败。接下来发生的事情是这样的:



注意,这里没有死锁,也没有慢查询。线程什么都没干,但它占着工位不放——这才是最要命的地方。

Thread.sleep 的语义是「让当前线程暂停执行」。暂停的意思是它不消耗 CPU,但它也没有被还回线程池,池子记着的账上,这个线程仍然在执行任务。于是等待的这 1 秒,等于从池子里白扣掉一个名额。

我们真正想要的其实是另一种画面:等待期间,线程先交回去,让别人用;时间到了,再捞一个线程回来接着干。



差别就在这一念之间:一边是「睡着等」,一边是「放下活、定个闹钟、走人」。JDK 9 之后,第二种写法不用自己去造轮子,标准库里已经有一个现成的闹钟。

这个闹钟叫delayedExecutor,是 CompletableFuture 上的一个静态方法:

一句话说清它的作用:返回一个特殊的 Executor,交给它的任务不会立刻跑,而是等指定时间之后才跑。

要理解它,得先知道 Executor 原本长什么样。它其实小得可怜,只有一个方法:



平时我们见到的都是「提交即执行」的实现,而这个闹钟版本是第三种:



它一共三个重载版本,覆盖了绝大多数用法:



最短的一个例子是这样:



跑出来的结果,重点看时间戳:



第三行那个线程名值得记住:延迟到期后,任务是被丢进公共池执行的,不是主线程,也不是你原来那个池。

很多人第一次看到这里会犯嘀咕:既然说「零额外线程占用」,那到底是谁在掐表?

答案是JDK 内部一个专门的守护线程(Delayer),它不占你的业务线程池,只负责一件事——计时。时间到了,它再把任务推给你指定的执行器:



所以那句「零额外线程占用」是有前提的:不占的是你的用户线程池。等待期间,你的池子一个线程都没被拖住,可以照常接单。

光讲道理没意思,直接做对照实验。场景:一个只有 1 个线程的线程池,塞进两个都要重试的任务,前几次一律失败、后面才成功。

先看阻塞版:



任务 B 硬生生等了 3 秒才等到第一次进场机会。现在换非阻塞版,核心改动只有一处——把 sleep 换成「定个闹钟再回来」:



同样 1 个线程、同样的失败次数,两种写法的账完全不一样:



这里有个写法上的小机关值得点一句:runAsync(() -> {}, …) 里的空 lambda 是故意的。我们不需要它做事,只需要借用它的「延迟」效果,真正的活儿放在 whenComplete 里,等 1 秒后再提交回线程池。

上面那版写起来还是有点散。工程里更常见的做法是封装成一个通用工具:创建一个空的 CompletableFuture 当「承诺」,失败就定闹钟、递归再来,成功或超限就把承诺兑现或作废。



调用端一句就够了,retryAsync 返回的还是个 CompletableFuture,可以继续挂 thenApply、allOf 这些操作:



整个链路的时间轴摊开看很清爽:提交任务 → 失败 → 定闹钟交还线程 → 到点 → 再提交。中间那段等待,线程池是自由的。

真实世界的服务抖动,往往不是等固定 1 秒就能好。更稳的做法是让等待时间逐次翻倍——100ms、200ms、400ms、800ms,也就是常说的指数退避。用上面这套骨架,改动小得惊人:



比起一上来就猛敲对方接口,这种「越等越久」的节奏对下游更友好,也更符合服务恢复的真实规律。如果这套写法是给自己项目用的,还可以顺手加上重试次数上限和熔断,别让它无限拖下去。

这个方法本身不复杂,坑基本都在用法上。挑五个最常见的:

  • 只创建不提交——单独写一句 delayedExecutor(1, SECONDS) 是没有任何效果的,它必须配合 runAsync / supplyAsync 使用,任务才会真的被排进去。
  • 该用 runAsync 却用了 supplyAsync——supplyAsync 要求 lambda 有返回值,没有 return 会直接编译不过;不需要返回值就用 runAsync。
  • 以为它会中断正在跑的任务——它只是个定时器,不取消、不打断任何已经在执行的任务,别把「延迟执行」理解成「延迟取消」。
  • 延迟回调里又去 get() 阻塞——好不容易把线程放回去了,回调里一发 get() 又堵上,等于白折腾。链式操作请继续用 thenCompose 之类的异步写法。
  • 不持有返回的 Future——主线程如果先退出,JVM 就关了,延迟任务根本没机会跑。至少把 Future 接住,必要时 get() 或 join() 等一下。

反过来,它也有明确的短板——只做「相对延迟」,不做「绝对时刻」,而且只延迟一次,不自动重复。下面这些需求,请换工具:



一句话给这个闹钟定位:它擅长「稍后再说」,不擅长「按时打卡」。

回到开头那个超时接口。同样的重试逻辑,把 sleep 换成 delayedExecutor,线程池就再也不会因为「等待」而排队了。这种改动的性价比很高——改一处,救一整池。

你在项目里是怎么写重试的?有没有被人吐槽过「sleep 太粗暴」?或者踩过 delayedExecutor 的什么坑?评论区说说,我挑几个有意思的展开聊~

声明:内容由AI生成

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
一名极为罕见的乌友

一名极为罕见的乌友

YY团长
2026-10-01 07:26:06
政府、国家、祖国三者不可混淆

政府、国家、祖国三者不可混淆

觉民行道
2026-10-01 11:31:29
今年的国庆招待会,有几个重要细节

今年的国庆招待会,有几个重要细节

政知新媒体
2026-10-01 19:24:09
终身不得糖尿病:为了不得糖尿病,请坚守这25条

终身不得糖尿病:为了不得糖尿病,请坚守这25条

鼠鼠健康图鉴
2026-10-01 06:00:15
葡媒:C罗已做出不可逆的决定,不会再代表葡萄牙国家队出战

葡媒:C罗已做出不可逆的决定,不会再代表葡萄牙国家队出战

懂球帝
2026-10-01 04:50:06
白宫文件称中国为盟友,坎贝尔激烈反对:别中了离间计

白宫文件称中国为盟友,坎贝尔激烈反对:别中了离间计

靓仔情感
2026-10-01 12:25:23
沉默一周后,一架美军运输机突降深圳,来要回F-35战机的零部件?

沉默一周后,一架美军运输机突降深圳,来要回F-35战机的零部件?

影孖看世界
2026-10-01 22:44:24
俄方寸步不让:天然气管道非得取道蒙古进入中国

俄方寸步不让:天然气管道非得取道蒙古进入中国

果妈聊娱乐
2026-10-01 16:13:46
国家队生涯结束?41岁C罗宣布离开葡萄牙队集训营:会适时公布真相

国家队生涯结束?41岁C罗宣布离开葡萄牙队集训营:会适时公布真相

我爱英超
2026-10-01 06:43:10
目不识丁,出尽洋相?于和伟在金鹰奖上的发言,给内娱明星上一课

目不识丁,出尽洋相?于和伟在金鹰奖上的发言,给内娱明星上一课

喜欢历史的阿繁
2026-10-01 12:34:18
伊拉克宣布实现国家完全主权

伊拉克宣布实现国家完全主权

新华社
2026-10-01 20:28:10
关晓彤西班牙度假,头秃装嫩土气狂晒脚丫,与助理深夜偷溜去酒吧

关晓彤西班牙度假,头秃装嫩土气狂晒脚丫,与助理深夜偷溜去酒吧

白面书誏
2026-10-01 14:51:49
夺机副驾驶社交账号曾谈“杀犹太人”,被制服后还要求别人杀了自己

夺机副驾驶社交账号曾谈“杀犹太人”,被制服后还要求别人杀了自己

桂系007
2026-10-02 00:28:24
安妮·海瑟薇挺三胎自曝:累到极限才发现自己有多能扛

安妮·海瑟薇挺三胎自曝:累到极限才发现自己有多能扛

影视情报室
2026-10-01 01:52:19
不止刘国梁恐怕连王励勤都没料到!被众人寄予厚望的孙颖莎,竟然输给了王曼昱

不止刘国梁恐怕连王励勤都没料到!被众人寄予厚望的孙颖莎,竟然输给了王曼昱

最爱乒乓球
2026-10-02 00:05:20
中国柔道名将亚运会被罚下判负!咬对手手臂20秒不松口 牙印曝光

中国柔道名将亚运会被罚下判负!咬对手手臂20秒不松口 牙印曝光

念洲
2026-10-01 20:55:42
美国一女囚被注射两剂死刑药物后仍有心跳,“还能听到她打鼾的声音”,行刑失败“接受抢救”

美国一女囚被注射两剂死刑药物后仍有心跳,“还能听到她打鼾的声音”,行刑失败“接受抢救”

大风新闻
2026-10-01 18:52:03
C罗大姐转发:葡萄牙不配拥有最好的人才,活该回到C罗前的平庸

C罗大姐转发:葡萄牙不配拥有最好的人才,活该回到C罗前的平庸

懂球帝
2026-10-01 04:18:07
你最好确定以色列拿不到“证据”

你最好确定以色列拿不到“证据”

走读新生
2026-10-01 17:44:04
伊朗内部发生激烈交火!安全部队出动坦克控局,准将级指挥官阵亡

伊朗内部发生激烈交火!安全部队出动坦克控局,准将级指挥官阵亡

比利
2026-10-01 12:36:52
2026-10-02 04:07:00
千纸鹤安安
千纸鹤安安
大自然的搬运工
151文章数 3关注度
往期回顾 全部

科技要闻

5999元起!华为Mate 90系列发布

头条要闻

桂林市文促会深夜发布致歉信:向阿丘诚恳致歉

头条要闻

桂林市文促会深夜发布致歉信:向阿丘诚恳致歉

体育要闻

“今天的表现,我们可以昂首离开球场”

娱乐要闻

奚梦瑶晒四太豪礼!22只龙凤镯近300万

财经要闻

智谱发上亿Token 能挽回开发者信任吗?

汽车要闻

2027款极氪001将于明年一季度上市 现款猎装同步推新配色

态度原创

数码
旅游
游戏
时尚
公开课

数码要闻

亚马逊发布全新Kindle:取消传统边框 正面屏幕实现全面平整化

旅游要闻

藏在黔北的小城湄潭,名字藏着古人的浪漫,读懂才知山水诗意!

《战争机器》新作GS 7分:创新不足剧情令人失望

在米兰,用时装唤醒内心的自我

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版