定时任务@Scheduled没有准时执行怎么解决

开发技术 作者:iii 2024-05-08 02:00:01
本文小编为大家详细介绍“定时任务@Scheduled没有准时执行怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“定时任务@Scheduled没有准时执行怎么解决”...

本文小编为大家详细介绍“定时任务@Scheduled没有准时执行怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“定时任务@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 // 开启定时任务

    定时任务@Scheduled没有准时执行怎么解决

    编写单线程demo

    定时任务@Scheduled没有准时执行怎么解决

    cron 表达式

    /**
         * cron 表达式
         * 每2秒执行一次
         * @throws InterruptedException
         */
        @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

     /**
         *  fixedDelay:
         *  第一次执行完毕才会执行第二次,时间间隔变为了7秒
         * @throws InterruptedException
         */
        @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()));
        }

    定时任务@Scheduled没有准时执行怎么解决

    fixedRate

     /**
         *  fixedRate:
         *  每隔2秒就会执行, 但是因为单线程,所以在5秒后会输出,间隔就是5秒
         * @throws InterruptedException
         */
        @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()));
        }

    定时任务@Scheduled没有准时执行怎么解决

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

    多线程

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

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

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

    @Async

    定时任务@Scheduled没有准时执行怎么解决

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

    定时任务@Scheduled没有准时执行怎么解决

    读到这里,这篇“定时任务@Scheduled没有准时执行怎么解决”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注捷杰建站行业资讯频道。

    原创声明
    本站部分文章基于互联网的整理,我们会把真正“有用/优质”的文章整理提供给各位开发者。本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
    本文链接:http://www.jiecseo.com/news/show_24767.html
    @scheduled