zoukankan      html  css  js  c++  java
  • Spring @Scheduler使用cron时的执行问题

    主要想弄清使用Spring @Scheduler cron表达式时的两个问题:

    • 同一定时任务,第二次触发时间到了,第一次还没有执行完成时会执行吗?
    • 不同的定时任务,相互之间是否有影响?

    结论写在前面:

    • 同一定时任务,第二次触发时间到了,第一次还没有执行完成时会执行吗?不会,会等前一次执行完成才执行下一次
    • 不同的定时任务,相互之间是否有影响?取决于可用的定时任务线程数,如果线程数足够则不会影响;如果可用定时任务线程数少于要执行定时任务数量,未能获取到线程的自然要等到有空闲线程时才能执行。

    下面是实验过程。。。。。

    使用Spring @Scheduler 时,默认只有一个线程,针对上面的问题,设计了3个实验:

    1. 设置Scheduler为多线程,设置一个线程5秒执行一次,方法体为 sleep8秒
    2. 使用Scheduler默认的单线程,设置两个线程都是5秒执行一次,一个 sleep8秒,一个不sleep
    3. 设置Scheduler为多线程,设置两个线程都是5秒执行一次,一个 sleep8秒,一个不sleep

    实验一

    设置Scheduler为多线程,设置一个线程5秒执行一次,方法体为 sleep8秒:

        @Scheduled(cron = "*/5 * * * * *")
        public void test1() throws InterruptedException {
            log.info("test1, 5秒执行一次,每次执行sleep 8s");
            Thread.sleep(8000L);
        }
    

    结果:

    2017-10-11 17:49:45 scheduler-1 test1, 5秒执行一次,每次执行sleep 8
    2017-10-11 17:49:55 scheduler-1 test1, 5秒执行一次,每次执行sleep 8
    2017-10-11 17:50:05 scheduler-1 test1, 5秒执行一次,每次执行sleep 8
    2017-10-11 17:50:15 scheduler-2 test1, 5秒执行一次,每次执行sleep 8
    2017-10-11 17:50:25 scheduler-2 test1, 5秒执行一次,每次执行sleep 8
    2017-10-11 17:50:35 scheduler-1 test1, 5秒执行一次,每次执行sleep 8

    结论:

    @Scheduled使用cron表达式,设置为多线程时,同一任务前一次没有执行完成,不会执行下一次

    实验二

    使用Scheduler默认的单线程,设置两个线程都是5秒执行一次,一个 sleep8秒,一个不sleep

    • 如果test2每8秒执行一次,则为串行
    	@Scheduled(cron = "*/5 * * * * *")
        public void test1() throws InterruptedException {
            System.out.println("test1, 5秒执行一次,每次执行sleep 8s");
            Thread.sleep(8000L);
        }
    
        @Scheduled(cron = "*/5 * * * * *")
        public void test2() {
            System.out.println("test2, 5秒执行一次,不sleep");
        }
    

    执行结果:

    2017-10-11 17:17:35 test2, 5秒执行一次,不sleep
    2017-10-11 17:17:35 test1, 5秒执行一次,每次执行sleep 8s
    2017-10-11 17:17:43 test2, 5秒执行一次,不sleep
    2017-10-11 17:17:45 test1, 5秒执行一次,每次执行sleep 8s
    2017-10-11 17:17:53 test2, 5秒执行一次,不sleep
    2017-10-11 17:17:55 test2, 5秒执行一次,不sleep
    2017-10-11 17:17:55 test1, 5秒执行一次,每次执行sleep 8s
    2017-10-11 17:18:03 test2, 5秒执行一次,不sleep
    2017-10-11 17:18:05 test2, 5秒执行一次,不sleep
    2017-10-11 17:18:05 test1, 5秒执行一次,每次执行sleep 8s
    2017-10-11 17:18:13 test2, 5秒执行一次,不sleep
    2017-10-11 17:18:15 test1, 5秒执行一次,每次执行sleep 8s
    2017-10-11 17:18:23 test2, 5秒执行一次,不sleep
    2017-10-11 17:18:25 test1, 5秒执行一次,每次执行sleep 8s

    对比期望执行时间:

    执行次数 task 期望执行时间 实际执行时间
    1 task1 17:17:35 17:17:35
    1 task2 17:17:35 17:17:35
    2 task1 17:17:40 17:17:43
    2 task2 17:17:40 17:17:45

    结论:

    @Scheduled使用cron表达式 ,配置为一个线程时,不同定时任务是串行执行,且上次没有执行完时不会执行下次

    实验三

    设置Scheduler为多线程,设置两个线程都是5秒执行一次,一个 sleep8秒,一个不sleep

    	@Scheduled(cron = "*/5 * * * * *")
        public void test1() throws InterruptedException {
            log.info("test1, 5秒执行一次,每次执行sleep 8s");
            Thread.sleep(8000L);
        }
    
        @Scheduled(cron = "*/5 * * * * *")
        public void test2() {
            log.info("test2, 5秒执行一次,不sleep");
        }
    

    结果:

    2017-10-11 18:12:40 scheduler-2 test2, 5秒执行一次,不sleep
    2017-10-11 18:12:40 scheduler-1 test1, 5秒执行一次,每次执行sleep 8s
    2017-10-11 18:12:45 scheduler-2 test2, 5秒执行一次,不sleep
    2017-10-11 18:12:50 scheduler-1 test1, 5秒执行一次,每次执行sleep 8s
    2017-10-11 18:12:50 scheduler-2 test2, 5秒执行一次,不sleep
    2017-10-11 18:12:55 scheduler-2 test2, 5秒执行一次,不sleep
    2017-10-11 18:13:00 scheduler-1 test1, 5秒执行一次,每次执行sleep 8s

    对比期望执行时间:

    执行次数 task 期望执行时间 实际执行时间
    1 task1 18:12:40 18:12:40
    1 task2 18:12:40 18:12:40
    2 task1 18:12:45 18:12:50
    2 task2 18:12:45 18:12:45

    结论:

    @Scheduled使用cron表达式 ,配置为多线程时,不同定时任务不是串行执行,且上次没有执行完时不会执行下次

    设置定时任务为多线程

    这里用的是spring boot:

    @Configuration
    public class ScheduleConfig {
    
        @Bean
        public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
            ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
            scheduler.setPoolSize(3);
            scheduler.setThreadNamePrefix("scheduler-");
            return scheduler;
        }
    
    }
    
  • 相关阅读:
    一天时间用python写门语言
    360以安全之名做搜索,可信,还是欺世盗名?
    Servicemix,Karaf和Camel
    Struts2>action 小强斋
    解决JBoss只能通过localhost(127.0.0.1)而不能通过IP访问 小强斋
    java.sql.SQLException: 关闭的连接 小强斋
    Struts2>action 小强斋
    flex>MXML语法 小强斋
    jsp>tomcat配置虚拟目录 小强斋
    解决JBoss只能通过localhost(127.0.0.1)而不能通过IP访问 小强斋
  • 原文地址:https://www.cnblogs.com/chrischennx/p/7652087.html
Copyright © 2011-2022 走看看