Springboot使用@Scheduled配置定时任务
串行方式
使用的注解: @Scheduled
应用启动类添加注解:@EnableScheduling
代码示例:
package com.bin.kong.csdnspider.job;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class TestJob {
@Scheduled(cron = "0/5 * * * * ?")
public void exec() {
log.info("Hello World!");
}
}
打印日志如下:
2019-09-28 19:02:15.002 INFO 40178 — [ scheduling-1] com.bin.kong.csdnspider.job.TestJob : Hello World!
2019-09-28 19:02:20.001 INFO 40178 — [ scheduling-1] com.bin.kong.csdnspider.job.TestJob : Hello World!
2019-09-28 19:02:25.003 INFO 40178 — [ scheduling-1] com.bin.kong.csdnspider.job.TestJob : Hello World!
定时任务Cron配置可参考:https://www.cnblogs.com/linjiqin/archive/2013/07/08/3178452.html
并行执行
串行执行的时候,可能会出现线程阻塞导致执行延时的情况.
代码示例:
package com.bin.kong.csdnspider.job;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class TestJob {
@Scheduled(cron = "0/5 * * * * ?")
public void exec() {
try {
Thread.sleep(1000*10);
log.info("Hello World!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Scheduled(cron = "0/5 * * * * ?")
public void exec2() {
log.info("World Hello!" );
}
}
结果打印,exec2的执行时间延时变成了15秒:
解决办法
1.使用线程池的方式:
配置方法可参考: Springboot线程池配置管理
代码示例:
package com.bin.kong.csdnspider.job;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class TestJob {
@Scheduled(cron = "0/5 * * * * ?")
public void exec() {
try {
Thread.sleep(1000*10);
log.info("Hello World!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Scheduled(cron = "0/5 * * * * ?")
@Async("threadExecutor")
public void exec2() {
log.info("World Hello!" );
}
}
2.使用Executors的方式
代码示例:
package com.bin.kong.csdnspider.job;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Component
@Slf4j
public class TestJob {
@Scheduled(cron = "0/5 * * * * ?")
public void exec() {
try {
Thread.sleep(1000 * 10);
log.info("Hello World!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Scheduled(cron = "0/5 * * * * ?")
public void exec2() {
ExecutorService service = Executors.newFixedThreadPool(5);
service.execute(() -> {
log.info("World Hello!");
});
}
}
3.将Scheduled配置成多线程执行的方式
示例代码:
package com.bin.kong.csdnspider.job;
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 ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
}
}
参数列表
参数名 | 描述 |
---|---|
corn | 可以使用Cron表达式来配置定时任务 |
fixedRate | 该属性的含义是上一次调用开始后再次调用的延时(不用等待上一次调用完成) |
fixedRateString | 含义同fixedRate,只是参数是String类型 |
fixedDelay | 该属性的含义是等一上次调用执行完成后再次调用的延时(需要等上一次调用完成) |
fixedDelayString | 含义同fixedDelay,只是参数是String类型 |
initialDelay | 该属性的含义是第一次执行的延时,需配合fixedRate等其他参数使用 |
initialDelayString | 含义同initialDelay,只是参数是String类型 |
zone | 与cron配合使用,指定所使用的时区。若不设置,则使用当前时区。 |