iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >解决定时任务@Scheduled没有准时执行的原因及分析
  • 837
分享到

解决定时任务@Scheduled没有准时执行的原因及分析

定时任务定时任务@Scheduled@Scheduled没准时执行 2023-05-17 11:05:21 837人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录定时任务@Scheduled没有准时执行的原因原因解决法案定时任务@Scheduled入门一个最简单的例子编写单线程demo多线程总结定时任务@Scheduled没有准时执行的原

定时任务@Scheduled没有准时执行的原因

项目中用到了定时任务往前端推送数据,间隔2秒 @Scheduled(cron = "0/2 * * * * ? "),测试发现,每次任务执行并不是2秒,而是1-5秒之间。

执行时间:::::Wed Nov 30 16:20:19 CST 2022
执行时间:::::Wed Nov 30 16:20:20 CST 2022
执行时间:::::Wed Nov 30 16:20:24 CST 2022
执行时间:::::Wed Nov 30 16:20:29 CST 2022

原因

了解发现,如果程序中没有指定线程池的配置,也就是spring的Scheduled的默认线程池配置,其线程池的线程数默认为1,也就是说默认情况下,Spring用来处理定时任务的线程只有一个。

如果有定时的处理时间占用时间比较长,那么就会导致下一个定时任务,即使到达了配置的定时时间,也不会立即执行,而是等到前面一个任务处理完成了,才会进行处理。

而项目中还有数个定时任务。

解决法案

是初始一个定时任务执行线程池

@Configuration
public class ScheduleConfig implements SchedulinGConfigurer {
 
    @Override
    public void configureTasks(ScheduledTaskReGIStrar taskRegistrar) {
        Method[] methods = BatchProperties.Job.class.getMethods();
        int defaultPoolSize = 10;
        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));
 
    }
}

再次测试,跟设置的间隔时间2秒一致。

执行时间:::::Wed Nov 30 16:48:32 CST 2022
执行时间:::::Wed Nov 30 16:48:34 CST 2022
执行时间:::::Wed Nov 30 16:48:36 CST 2022
执行时间:::::Wed Nov 30 16:48:38 CST 2022

定时任务@Scheduled入门

一个最简单的例子

启动类添加注解

@EnableScheduling // 开启定时任务

编写单线程demo

cron 表达式


    @Scheduled(cron = "0/2 * * * * *")
    public void test() throws InterruptedException {
        // 经过测试,使用cron表达式,定时任务第二次会等待第一次执行完毕再开始!
        Thread.sleep(5000L);
        log.info("定时任务测试cron:" + new SimpleDateFORMat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

fixedDelay

 
    @Scheduled(fixedDelay = 2000L)
    public void test2() throws InterruptedException {
        Thread.sleep(5000L);
        log.info("定时任务测试fixedDelay:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

fixedRate

 
    @Scheduled(fixedRate = 2000L)
    public void test3() throws InterruptedException {
        Thread.sleep(5000L);
        log.info("定时任务测试fixedRate:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

如果是一起执行这三个定时任务,那么会一个一个的来, 因为只有一个线程.

多线程


@Configuration
@EnableAsync
public class ScheduleConfig {
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(50); // 设置线程池大小
        return taskScheduler;
    }
}

如果只是加这一个配置类, 确实是使用了多线程, 每个定时任务都互相不影响.

但是一个线程第一次阻塞了,第二次就不行了,所以在定时任务上再加

@Async

就是说你这次失败了, 不要影响我下次的运行

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: 解决定时任务@Scheduled没有准时执行的原因及分析

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

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

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

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

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

  • 微信公众号

  • 商务合作