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 框架中使用异步任务,定时任务和邮件任务
Spring专题「开发指南」手把手教你将@Schedule任务调度升级为分布式调度@DistributeSchedule