美文网首页
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