首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Java避坑指南:ScheduledThreadPoolExecutor避坑之异常信息会丢失,任务不再继续被调度的源码分析

Java避坑指南:ScheduledThreadPoolExecutor避坑之异常信息会丢失,任务不再继续被调度的源码分析

作者头像
崔认知
发布2023-06-20 11:20:15
发布2023-06-20 11:20:15
9550
举报
文章被收录于专栏:nobodynobody

简介


在上篇博文中提到了ScheduledThreadPoolExecutor的一个坑:异常信息会丢失,任务不再继续被调度

Java避坑指南:ScheduledThreadPoolExecutor避坑

下面我们以源码的形式分析这种情况。

ScheduledThreadPoolExecutor异常信息会丢失,任务不再继续被调度的源码分析


当我们提交周期性调度的任务时,会先把任务存储到延迟队列DelayedWorkQueue中,以方法:

代码语言:javascript
复制
ScheduledThreadPoolExecutor#scheduleAtFixedRate

为例:

当线程池中的核心线程从队列中获取任务执行时:

代码语言:javascript
复制
ScheduledThreadPoolExecutor.ScheduledFutureTask#run

任务是周期性执行,代码逻辑走红色框内,任务执行并重置逻辑:super.runAndReset(),

如果super.runAndReset()执行成功,才会更新任务的下次执行时间,并把任务入队,等待下次调度执行如果super.runAndReset()失败,则不会再次调度此任务

我们看一下如果被调度的任务抛出异常,super.runAndReset()返回true还是fals:

异常发生后,会保存异常,不再抛出,不主动调用Future#get(),异常信息会丢失,调度任务一般不会调用Future#get(),所以调度的任务发送异常信息会丢失。

任务发生异常后,super.runAndReset()最后一行,根据任务的执行结果ran与任务的执行状态state判断:ran && s == NEW 结果返回false,即:被周期性调度的任务一旦抛出异常,此任务不会再被调度。

小结


使用ScheduledThreadPoolExecutor来周期性的调度任务时,我们一定不要抛出异常,从而导致异常信息丢失,也导致周期性被调度的任务不再继续被调度执行。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-10-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 认知科技技术团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档