在java 开发环境中,我们经常会需要用到定时任务来帮助我们完成一些特殊的任务,比如晚上12点清理脏数据等等,凌晨三点清理计算报表等。
如果我们使用SpringBoot来开发,那么定时任务将会变得非常简单。SpringBoot默认已经帮我们封装好了相关定时任务的组件和配置,我们只需要在相应的地方加上@EnableScheduling注解就可以实现定时任务。
SpringBoot项目只需要在启动类上加上@EnableScheduling即可开启定时任务
@SpringBootApplication
@EnableScheduling
public class ScheduleTestApplication {
public static void main(String[] args) {
SpringApplication.run(ScheduleTestApplication.class, args);
}
}
创建定时任务
SpringBoot的Scheduler支持四种定时任务格式
- fixedRate:固定速率执行,例如每3秒执行一次
- fixedDelay:固定延迟执行,例如距离上一次调用成功后3秒执行
- initialDelay:初始延迟任务,例如任务开启过3秒后再执行,之后以固定频率或者间隔执行
- cron:使用 Cron 表达式执行定时任务
当然使用最多的还是cron
使用cron表达式
@Component
public class ScheduledTasks {
private Logger logger = LoggerFactory.getLogger(ScheduledTasks.class);
// cron接受cron表达式,根据cron表达式确定定时规则
@Scheduled(cron="0/5 * * * * ? ") //每5秒执行一次
public void testCron() {
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
logger.info(sdf.format(new Date())+"*********每5秒执行一次");
}
@Scheduled(cron="0/5 * * * * ? ") //每5秒执行一次
public void testCron1() {
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
logger.info(sdf.format(new Date())+"*********每5秒执行一次");
}
}
当定时任务执行时你会发现他们是同一个线程执行的,是串行执行的
解决方案那么,怎么设计成多线程实现并发呢?在网上看到过这样的解决方案。通过ScheduleConfig配置文件实现SchedulingConfigurer接口,并重写setSchedulerfang方法,我们尝试着配置了一下。
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
}
}
或者
Spring Boot 版本2.1.0之后,可以直接在配置文件中设置 spring.task.scheduling.pool.size 的值来配置计划任务线程池的容量,而不需要额外再写一个类。
spring.task.scheduling.pool.size=5



