先說說@EnableScheduling這個注解 , 之前一直疑惑有的地方為什么沒有@EnableScheduling這個注解也可以正常運行呈野,其實這個注解相當于一個全局開關(guān) , 讓該項目可以掃描到@Schedule方法 , 所以在項目某一處用到了@EnableScheduling , 其他地方也可以作用到。
1. fixDelay和fixRate的一個區(qū)別
定時任務(wù)參數(shù)fixDelay的間隔為第一次任務(wù)的結(jié)束和第二次任務(wù)的開始 , 如果是參數(shù)fixRate , 間隔則為兩次任務(wù)的開始印叁。參數(shù)fixRate下,如果程序執(zhí)行時間大于設(shè)置的間隔時間,則會在結(jié)束時立馬執(zhí)行下一次任務(wù).
2. spring schedule的非重入性
值得注意的,spring schedule默認為單線程,且不會被重入,也就是說一個@EnableScheduling類里同一時間只有一個定時任務(wù)可以啟動,如果要同時執(zhí)行兩個定時任務(wù)怎么辦?
解決辦法:
- 1.配置參數(shù)為多線程
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.兩個任務(wù)分別寫在兩個@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();
}
}
}
}
}
測試結(jié)果:可以看到 , 設(shè)置了線程池之后可以變成多線程執(zhí)行 , 但是此時依舊是非重入的(也就是某個方法執(zhí)行完后才會再次被執(zhí)行)