06 Spring 异步执行,任务调度(@Schedule、@Async)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了06 Spring 异步执行,任务调度(@Schedule、@Async)相关的知识,希望对你有一定的参考价值。

参考技术A 在写Spring 应用的时候,会遇到一些异步执行和任务调度的问题,例如:Spring MVC中需要向微信发送请求,告诉微信进行公众号推送。这个时候需要用到异步执行,而周报表、月报表、日最高点击等,需要用到任务调度。
Spring高度凝聚了及其简单的调度和异步执行方式,迅速解决百分之八十的问题。

https://github.com/laiyijie/SpringLearning

运行具有Main函数的 App.java
得到如下输出

从App.java入手

主函数中有一个for循环,调用的是 HelloInterface 的 sayHello 方法。
并且主线程休眠了10秒后关闭 ApplicationContext 。

接口,并定义了两个函数,其实现类为 UserServiceImpl

实现了两个函数,而且两个函数前面分别有 @Async 和 @Scheduled 两个注解。
分别探讨:

被 @Async 标注过的方法不是在主线程中执行,是另开了一个线程,并且进行调度,从打印就可以看出,调度是随机的!

既然涉及到异步,就涉及到线程池有多大?队列有多大?
root-context.xml中有如下配置:

pool-size=5 : 线程池的大小为5!
queue-capacity=100 : 等待队列的最大长度为100!

所以可以看到,前面的输出,0-4次 userHello 在5-9次前面,因为一次只能同时执行五个线程。

被 @Scheduled 标注过的函数会按照配置的运行方式 自动执行 !此处配置的是 fixedDelay=1000 含义是每隔1000ms执行一次(在上次执行完后开始计时1000ms)
定时调度一样有一个线程池:

含义与 executor 一致

需要开启 @Async 和 @Scheduled ,root-context.xml需要进行如下配置:

变更如下:

虽然可以最简单的使用:

但是建议还是自己定义 executor 和 scheduler 方便控制资源大小

SpringBoot任务调度

参考技术A SpringBoot提供了任务调度功能,可以指定启动服务器立刻执行某些任务逻辑,或指定时间调用某些任务逻辑。

SpringBoot提供了 ApplicationRunner 和 CommandLineRunner 接口,实现任何一个即可。

1. ApplicationRunner

2. CommandLineRunner

总结:多个任务可以使用@Order定义调度顺序,从1,2,3,4...;多个任务采用单线程同步模式执行。

如果需要多个任务需要异步执行调用,可以使用 @EnableAsync 和 @Async 标记。

提示:在需要的时机注入MyTask3任务对象,调用run1、run2方法。

在以前经常使用 Quartz 工具来实现任务调度。后期Spring框架引入 Schedule 任务模块,实现了任务调度功能。( Spring+Quartz 、 Spring Schedule )

1. Spring Schedule模块应用

cron表达式( 由7部分构成,格式为“秒 分  时  日  月  星期  年” )

2. Spring Quartz整合应用

编写任务组件

配置JobDetail、CronTrigger、ScheduleFactoryBean组件

以上是关于06 Spring 异步执行,任务调度(@Schedule、@Async)的主要内容,如果未能解决你的问题,请参考以下文章

微服务架构中的任务调度:在 SpringBoot 框架中使用异步任务,定时任务和邮件任务

SpringBoot任务调度

Spring专题「开发指南」手把手教你将@Schedule任务调度升级为分布式调度@DistributeSchedule

mysql开启定时调度任务执行

Java SpringTask定时任务

任务调度(02)Spring Schedule