定时任务调度功能在我们的开发中是非常常见的,随便举几个例子:定时清除一些过期的数据,定时发送邮件等等,实现定时任务调度的方式也十分多样,本篇文章主要学习各种实现定时任务调度方式的优缺点,以便为日后选择的时候提供一定的参考 。
本篇要点
- 介绍Timer实现定时任务 。
- 介绍ScheduledExecutorService实现定时任务 。
- 介绍SpringBoot使用SpringTask实现定时任务 。
- 介绍SpringBoot使用SpringTask实现异步任务 。
缺点:
- 无法指定某一时间的时候执行 。
- 存在潜在bug,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行 。
public class DemoTimer {//延时时间private static final long DELAY = 3000;//间隔时间private static final long PERIOD = 5000;public static void main(String[] args) {// 定义要执行的任务TimerTask task = new TimerTask() {@Overridepublic void run() {System.out.println("任务执行 --> " + LocalDateTime.now());}};Timer timer = new Timer();timer.schedule(task, DELAY, PERIOD);}}
ScheduledExecutorService实现定时任务阿里巴巴开发规范明确规定:希望开发者使用ScheduledExecutorService代替Timer 。多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题 。
public class DemoScheduledExecutorService {//延时时间private static final long DELAY = 3000;//间隔时间private static final long PERIOD = 5000;public static void main(String[] args) {Runnable task = new Runnable() {@Overridepublic void run() {System.out.println("任务执行 --> " + LocalDateTime.now());}};ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();service.scheduleAtFixedRate(task, DELAY, PERIOD, TimeUnit.MILLISECONDS);}}
SpringBoot使用Spring Task实现定时任务自动配置实现原理Spring为我们提供了异步执行任务调度的方式,提供TaskExecutor,TaskScheduler接口,而SpringBoot的自动配置类org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration为我们默认注入了他们的实现:ThreadPoolTaskScheduler,本质上是ScheduledExecutorService 的封装,增强在调度时间上的功能 。文章插图
@ConditionalOnClass(ThreadPoolTaskScheduler.class)@Configuration(proxyBeanMethods = false)@EnableConfigurationProperties(TaskSchedulingProperties.class)@AutoConfigureAfter(TaskExecutionAutoConfiguration.class)public class TaskSchedulingAutoConfiguration { @Bean @ConditionalOnBean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME) @ConditionalOnMissingBean({ SchedulingConfigurer.class, TaskScheduler.class, ScheduledExecutorService.class }) public ThreadPoolTaskScheduler taskScheduler(TaskSchedulerBuilder builder) {return builder.build(); } @Bean @ConditionalOnMissingBean public TaskSchedulerBuilder taskSchedulerBuilder(TaskSchedulingProperties properties,ObjectProvider<TaskSchedulerCustomizer> taskSchedulerCustomizers) {TaskSchedulerBuilder builder = new TaskSchedulerBuilder();builder = builder.poolSize(properties.getPool().getSize());Shutdown shutdown = properties.getShutdown();builder = builder.awaitTermination(shutdown.isAwaitTermination());builder = builder.awaitTerminationPeriod(shutdown.getAwaitTerminationPeriod());builder = builder.threadNamePrefix(properties.getThreadNamePrefix());builder = builder.customizers(taskSchedulerCustomizers);return builder; }}
新建工程,引入依赖Spring Task是Spring Framework中的模块,我们只需引入spring-boot-starter依赖就可以了 。<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency>
编写配置类@EnableScheduling@Configuration@EnableSchedulingpublic class ScheduleConfig {}
- @Configuration表明这是个配置类 。
- @EnableScheduling表明启用Spring的定时任务调度功能 。
@Component@Slf4jpublic class DemoTask {private final AtomicInteger counts = new AtomicInteger();@Scheduled(cron = "0/5 * * * * *")public void execute() {log.info("[定时任务第 {} 次执行]", counts.incrementAndGet());}}
- @Component表明该类需要被扫描,以便于Spring容器管理 。
- @Scheduled标注需要调度执行的方法,定义执行规则,其必须指定cron、fixedDelay或fixedRate三个属性其中一个 。cron:定义Spring cron表达式,网上有在线cron生成器,可以对照着编写符合需求的定时任务 。fixedDelay :固定执行间隔,单位:毫秒 。注意,以调用完成时刻为开始计时时间 。fixedRate :固定执行间隔,单位:毫秒 。注意,以调用开始时刻为开始计时时间 。
推荐阅读
- 中国联通|日赚3.87亿!三大运营商财报中的小秘密
- 白云山中的茶源胜境,灵与元居士青山潭饮茶饮茶诗歌作品
- 2016版word表格中文字上下居中方法-2013word表格中的文字怎么上下居中-
- 红楼梦中的端午节
- 六道中的阿修罗是什么?
- 历史中的甘罗 历史上的甘罗最后到底怎么样
- 基于SpringBoot的微服务架构与K8S容器部署实践
- 三国演义中的空城计 三国空城计真相
- 杨家将著名将领是谁 杨家将中的人物
- 家里无线网络每天不定时段出现网速很慢或者直接无连接,这是怎么回事?