SpringBoot 使用@Scheduled注解配置串行、并行定时任务

三种: 
1) Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。 最早的时候就是这样写定时任务的。 
2) 开源的第三方框架: Quartz 或者 elastic-job , 但是这个比较复杂和重量级,适用于分布式场景下的定时任务,可以根据需要多实例部署定时任务。 
3) 使用Spring提供的注解: @Schedule 。 如果定时任务执行时间较短,并且比较单一,可以使用这个注解。

定时任务的创建
存在两种调度方式: 单线程和多线程

串行方式

使用的注解: @Scheduled 和 @EnableScheduling

@Slf4j
@Component
public class ScheduledController {undefined
@Autowired
ScheduledServiceImpl scheduledService;

@Scheduled(cron = "0 0/2 * * * ?")
public void pushDataScheduled(){undefined
    log.info("start push data scheduled!");
    scheduledService.pushData();
    log.info("end push data scheduled!");
}
 


并行方式

当定时任务很多的时候,为了提高任务执行效率,可以采用并行方式执行定时任务,任务之间互不影响, 
只要实现SchedulingConfigurer接口就可以。

/**
    定时任务并行执行
**/
@Configuration
public class ScheduledConfig implements SchedulingConfigurer {undefined
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {undefined
    scheduledTaskRegistrar.setScheduler(setTaskExecutors());
}

@Bean(destroyMethod="shutdown")
public Executor setTaskExecutors(){undefined
    return Executors.newScheduledThreadPool(3); // 3个线程来处理。
}}
 


5.cron表达式
常用: 秒、分、时、日、月、年

0 0 10,14,16 * * ? 每天上午10点,下午2点,4点 
0 0 12 * * ? 每天中午12点触发 
0 0/5 0 * * ? 每5分钟执行一次

具体更多可以参考: https://www.cnblogs.com/linjiqin/archive/2013/07/08/3178452.html

6.深入理解,使用延迟队列代替定时任务
在并行执行的时候,创建线程池采用了newScheduledThreadPool这个线程池。 Executors框架中存在几种线程池的创建,一种是 newCachedThreadPool() ,一种是 newFixedThreadPool(), 一种是 newSingleThreadExecutor()

其中newScheduledThreadPool() 线程池的采用的队列是延迟队列。newScheduledThreadPool() 线程池的特性是定时任务能够定时或者周期性的执行任务。

源码: 
public ScheduledThreadPoolExecutor(int corePoolSize) {undefined
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
          new DelayedWorkQueue());
}

其中线程池核心线程数是自己设定的,最大线程数是最大值。阻塞队列是自定义的延迟队列:DelayedWorkQueue()
 

上一篇:springboot系列11: 定时任务


下一篇:后端开发杂记-springboot之定时任务