先说说@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();
}
}
}
}
}
测试结果:可以看到 , 设置了线程池之后可以变成多线程执行 , 但是此时依旧是非重入的(也就是某个方法执行完后才会再次被执行)