spring schedule的线程与重入问题

先说说@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();
                }
            }
        }
    }
}

测试结果:

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容