美文网首页
spring schedule的线程与重入问题

spring schedule的线程与重入问题

作者: 冒险小A | 来源:发表于2019-08-14 12:17 被阅读0次

    先说说@EnableScheduling这个注解 , 之前一直疑惑有的地方为什么没有@EnableScheduling这个注解也可以正常运行,其实这个注解相当于一个全局开关 , 让该项目可以扫描到@Schedule方法 , 所以在项目某一处用到了@EnableScheduling , 其他地方也可以作用到。

    1. fixDelay和fixRate的一个区别

    定时任务参数fixDelay的间隔为第一次任务的结束和第二次任务的开始 , 如果是参数fixRate , 间隔则为两次任务的开始。参数fixRate下,如果程序执行时间大于设置的间隔时间,则会在结束时立马执行下一次任务.

    2. spring schedule的非重入性

    值得注意的,spring schedule默认为单线程,且不会被重入,也就是说一个@EnableScheduling类里同一时间只有一个定时任务可以启动,如果要同时执行两个定时任务怎么办?

    解决办法:

    • 1.配置参数为多线程
      springboot配置类
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.SchedulingConfigurer;
    import org.springframework.scheduling.config.ScheduledTaskRegistrar;
    
    import java.util.concurrent.Executors;
    
    @Configuration
    public class ScheduleConfigration implements SchedulingConfigurer {
        @Override
        public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
        }
    }
    
    
    
    • 2.两个任务分别写在两个@EnableScheduling类里
    3. 代码测试
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    @Component
    @EnableScheduling
    public class Demo7 {
    
        @Scheduled(initialDelay = 5 * 1000, fixedRate = 2 * 1000)
        void doit() {
            for (int i = 0; i < 10; i++) {
                System.out.println("第" + i + "次输出");
                if (i != 9) {
                    try {
                        Thread.sleep(2 * 1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        @Scheduled(initialDelay = 7 * 1000, fixedDelay = 2 * 1000)
        void doit2() {
            for (int i = 0; i < 10; i++) {
                System.out.println("第" + i + "次哈哈哈");
                if (i != 9) {
                    try {
                        Thread.sleep(2 * 1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    测试结果:

    可以看到 , 设置了线程池之后可以变成多线程执行 , 但是此时依旧是非重入的(也就是某个方法执行完后才会再次被执行)

    相关文章

      网友评论

          本文标题:spring schedule的线程与重入问题

          本文链接:https://www.haomeiwen.com/subject/yvqgjctx.html