当前位置: 首页 > 后端技术 > Java

又被问到:SpringBoot定时任务启动后,如何满足条件自动停止?

时间:2023-04-01 23:56:08 Java

背??景昨天我们《知识星球:Java技术栈》有粉丝问我一个问题:问题大概是:SpringBoot定时任务启动后,如何满足条件自动停止?我当时有空,虽然已经给出了参考答案,但可能还有一些细节需要注意。另外,我也觉得这个问题很有意思,所以整理出来分享给大家。1,,定义任务首先覆盖覆盖覆盖覆盖覆盖覆盖ut?>>scheduledTasks=newIdentityHashMap<>();@OverridepublicSc??heduledFutureschedule(Runnabletask,Trigger触发器){ScheduledFuturefuture=super.schedule(task,trigger);this.putScheduledTasks(任务,未来);返回未来;}@OverridepublicSc??heduledFuturescheduleAtFixedRate(Runnabletask,longperiod){ScheduledFuturefuture=super.scheduleAtFixedRate(task,period);this.putScheduledTasks(任务,未来);返回未来;}@OverridepublicSc??heduledFuturescheduleAtFixedRate(Runnabletask,DatestartTime,longperiod){ScheduledFuturefuture=super.scheduleAtFixedRate(任务、开始时间、期间);this.putScheduledTasks(任务,未来);返回未来;}privatevoidputScheduledTasks(Runnabletask,ScheduledFuturefuture){ScheduledMethodRunnablerunnable=(ScheduledMethodRunnable)task;scheduledrunnable(getTarget.put(),未来);}//Rewriteallschedule*methods...}SpringBoot基础就不介绍了,推荐这个实用教程:https://github.com/javastacks...Rewriteallschedule*methods...因为要停一个task,必须调用ScheduledFuture->Future接口中的cancel方法。所以,思路是在任务执行时,把任务所在的实例Bean和任务启动后的ScheduledFuture维护在一个Map中,然后需要停止的时候,从Map中取出来,然后cancel到停止。2.根据条件自动停止任务创建一个每3秒执行一次的新任务:/***根据条件自动停止任务*公众号:Java技术栈*/@Slf4j@ComponentpublicclassAutoStopTask{@AutowiredprivateCustomTaskSchedulercustomTaskScheduler;私人整数计数;@Scheduled(cron="*/3*****")publicvoidprintTask(){log.info("公众号Java技术栈,任务执行次数:{}",count+1);计数++;//执行3次后自动停止if(count>=3){log.info("任务已执行指定次数,现在自动停止");布尔取消=customTaskScheduler.getScheduledTasks().get(this).cancel(true);//停止后重启if(cancelled){count=0;ScheduledMethodRunnablerunnable=newScheduledMethodRunnable(this,ReflectionUtils.findMethod(this.getClass(),"printTask"));customTaskScheduler.schedule(runnable,newCronTrigger("*/3*****"));}}}}这里是统计执行,当执行次数超过3次,会自动停止。如果需要重新启动,上面还提供了参数代码。需要注意的是,自定义调度绑定了实例bean和Future的关系,所以仅限于bean中的单个任务。如果一个bean维护了多个任务,那么最后一个任务的开始会覆盖之前的任务。如果要在bean中维护多个任务,应该怎么做才能自动停止呢?答案是将任务的方法名与Future相关联:/scheduledMethodTasks.put(runnable.getMethod(),future);方法名可以根据当前方法名来选择,这里是方法名,也可以是类名+方法名+参数,防止重复。关于这个问题,您还有哪些实施计划?欢迎留言分享!总结本文完整的示例代码已经上传到Github:https://github.com/javastacks...有兴趣的可以Star学习,后续会持续更新。最后来一波我们星球的广告:如果你也有很多疑难问题和疑惑无法解答,可以加入我们的《知识星球:Java技术栈》,只要我认识的店长,我都会解答,还有2500+高尔夫球手;如果你学习没有方向,工作没有提升,而《知识星球:Java技术栈》包含大量的技术知识,学习资料,面试题,简历模板等等,加入的话还是值得的;加入的好时机,过段时间肯定会恢复原价。公众号,微信好友太多,不可能一一回答大家的问题,时间和精力都不允许(回答是感情问题,不回答是义务),所以我创建了《知识星球:Java技术栈》,知识付费,现在已经成为一种责任。stackmanager是一个纯技术人员,不耍花样,从不耍花招。我们的星球绝对物有所值。欢迎加入我们一起学习。最后,如果你想关注和学习最新最主流的Java技术,可以持续关注公众号Java技术栈,第一时间推送公众号。版权声明:本文为公众号《Java技术栈》原创。转载、引用本文内容请注明出处。抄袭、洗稿均属侵权投诉,后果自负,并保留追究法律责任的权利。近期热点文章推荐:1.1000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!