iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >springboot使用定时器@Scheduled不管用的解决方法
  • 153
分享到

springboot使用定时器@Scheduled不管用的解决方法

2023-06-22 06:06:42 153人浏览 薄情痞子
摘要

SpringBoot使用定时器@Scheduled不管用的解决方法,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。使用定时器@Scheduled不管用如果是一开始就不能用就是

SpringBoot使用定时器@Scheduled不管用的解决方法,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

使用定时器@Scheduled不管用

如果是一开始就不能用就是没写@EnableScheduling注解,如果是用着用着不管用了 是因为@Scheduled是单线程,有定时器在工作或者没有运行完毕,所以造成了线程堵塞所以导致下一个定时器不能运行增加一个方法类

package com.llt;import org.springframework.boot.autoconfigure.batch.BatchProperties;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.scheduling.annotation.SchedulinGConfigurer;import org.springframework.scheduling.config.ScheduledTaskReGIStrar;import java.lang.reflect.Method;import java.util.concurrent.Executors;@Configurationpublic class ScheduleConfig implements SchedulingConfigurer {    @Override    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {        Method[] methods = BatchProperties.Job.class.getMethods();        int defaultPoolSize = 3;        int corePoolSize = 0;        if (methods != null && methods.length > 0) {            for (Method method : methods) {                Scheduled annotation = method.getAnnotation(Scheduled.class);                if (annotation != null) {                    corePoolSize++;                }            }            if (defaultPoolSize > corePoolSize)                corePoolSize = defaultPoolSize;        }        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(corePoolSize));    }}

就好了!

多个@Scheduled定时器不执行

最近项目中经常有用到@Scheduled注解,在内测时由于数据量小(没有进行压力测)所以每个线程执行都很快,但线上后发现部分功能无法使用,最后定位是部分的定时器没有执行,后查阅资料和Springboot源码

springboot使用定时器@Scheduled不管用的解决方法

springboot使用定时器@Scheduled不管用的解决方法

ScheduledTaskRegistrar在启动时,如果没有指定线程池的大小,默认会创建核心线程数为1的默认线程池,故而当项目中出现多个@Scheduled线程时,只能一个个的执行,从而导致个别线程执行时间过长(或长期执行)时,其他定时器不能按照指定的规则进行执行。

解决方法

在项目初始化时指定其执行线程池的大小

import org.springframework.boot.autoconfigure.batch.BatchProperties;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.scheduling.annotation.SchedulingConfigurer;import org.springframework.scheduling.config.ScheduledTaskRegistrar; import java.lang.reflect.Method;import java.util.Arrays;import java.util.Objects;import java.util.concurrent.ScheduledThreadPoolExecutor;import java.util.concurrent.atomic.AtomicInteger; @Configurationpublic class ScheduledTaskConfiguration implements SchedulingConfigurer {    @Override    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {        Method[] methods = BatchProperties.Job.class.getMethods();        final AtomicInteger corePoolSize = new AtomicInteger();        if (Objects.nonNull(methods) && methods.length > 0) {            Arrays.stream(methods).forEach(method -> {                final Scheduled annotation = method.getAnnotation(Scheduled.class);                if (Objects.nonNull(annotation)) {                    corePoolSize.incrementAndGet();                }            });        }        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(corePoolSize.get());        taskRegistrar.setScheduler(executor);    }}

将定时器设置为异步线程

@Async("taskExecutor")@Scheduled(initialDelay = 1000L, fixedDelay = 3000L)public void test(){   System.out.println("---"+System.currentTimeMillis()); //业务内容}

关于springboot使用定时器@Scheduled不管用的解决方法问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网精选频道了解更多相关知识。

--结束END--

本文标题: springboot使用定时器@Scheduled不管用的解决方法

本文链接: https://www.lsjlt.com/news/303014.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作