版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
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));
}
}