1.异步任务
在项目开发中,针对耗时业务逻辑,往往采用多线程来处理此任务。在Spring中使用异步任务极为方便,只需要一个@Async注解即可将任务加入线程池运行,极大的提高了开发效率。
1.1 使用异步任务
默认情况下,无需做任何额外配置,只需要以下两步便可使用SpringBoot的异步任务:
- 在启动类加上@EnableAsync注解,开启注解使用异步任务的功能;
- 在想要异步执行的方法前加上@Async注解,同时需要将该方法所在类注入Spring IOC容器,该方法在被调用时将异步执行。
启动类代码:
@SpringBootApplication
@EnableAsync
public class SpringBootTaskApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootTaskApplication.class, args);
}
}
异步任务代码如下:
@Service
public class AsyncService {
@Async
public void ProtocolInterpreter()
{
try {
//模拟耗时操作
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":协议解析完成");
}
}
调用异步任务:
@RestController
public class HelloController {
@Autowired
AsyncService asyncService;
@GetMapping("/hello")
public String hello() {
asyncService.ProtocolInterpreter();
asyncService.ProtocolInterpreter();
asyncService.ProtocolInterpreter();
return "success";
}
}
在浏览器访问地址http://localhost:8080/hello,success会被立刻返回
控制台打印:
1.2 配置异步任务
默认情况下,我们无需对SpringBoot的异步任务做任何特殊配置便可使用。但在一些要求比较高的应用中,SpringBoot的默认配置并不能满足我们的需求。这就需要我们手动配置了:
spring:
task:
execution:
#配置线程池名称前缀
thread-name-prefix: async-task-
pool:
#配置核心线程数,即线程池创建时的初始化大小,SpringBoot2.2默认值为8
core-size: 10
#配置最大线程数,SpringBoot2.2默认值为2147483647
max-size: 100
#配置缓冲队列数,用来存放待执行的任务,SpringBoot2.2默认值为2147483647
#当待执行的线程数超过此队列大小时,Spring会将线程数增加,上限为所配置的最大线程数
queue-capacity: 1000
#配置线程最大空闲时间,线程空闲时间超过此时间,将被回收,SpringBoot2.2默认值为60(s)
keep-alive: 20s
上面列出的配置文件中,我们做了以下配置:
- thread-name-prefix: 配置线程名称前缀,默认为task-
- pool.core-size: 配置线程池初始化时创建的线程个数
- pool.max-size: 配置线程池最大线程数
- pool.queue-capacity: 配置线程缓冲队列大小,如果缓冲队列达到了上限,Spring会将线程数增加,上限为pool.max-size
- pool.keep-alive: 配置线程最大空闲时间,超过此时间,线程将会被回收
2.定时任务
在实际项目中往往还需要定时任务,比如定时清理日志、定时备份数据库中的数据、定时统计数据做报表等等。下面就来看一看SpringBoot的定时任务怎么用吧。
2.1 使用定时任务
只需要以下两个步骤,便可使用SpringBoot的定时任务:
- 在启动类添加@EnableScheduling注解,开启注解使用定时任务的功能
- 在要定时执行的方法前加上@Scheduled注解,同时需要将该方法所在类注入Spring IOC容器
启动类代码:
@SpringBootApplication
@EnableAsync
@EnableScheduling
public class SpringBootTaskApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootTaskApplication.class, args);
}
}
定时任务代码如下:
@Service
public class ScheduledService {
@Scheduled(cron = "*/1 * * * * *")
public void tellTime()
{
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println("currentTime:" + simpleDateFormat.format(new Date()));
}
}
上面这段代码1s执行一次,作用是打印当前时间。
2.2 cron表达式详解
格式:cron = " 秒 分 时 日 月 星期几 "
属性 | 取值范围 | 特殊符号 |
---|---|---|
秒 | 0-59 | , - * / |
分 | 0-59 | , - * / |
时 | 0-59 | , - * / |
日 | 1-31 | , - * / ? L W C |
月 | 1-12 | , - * / |
星期几 | 0 - 7(0、7都代表周日) | , - * / ? L C # |
特殊符号解释
符号 | 含义 |
---|---|
, | 以逗号分割指定多个值 |
- | 区间 |
* | 任意 |
/ | 步长 |
? | 日/星期冲突匹配。比如: * * * ? * 1 每周1执行,则日用 ? 不能用 * , 不是每一天都是周一; * * * 2 * ? 每月2号,则星期不能用* |
L | 最后 |
W | 工作日 |
# | 这个月的第几个星期几 如3#2代表这个月的第2个星期三 |
用法举例:
表达式 | 含义 |
---|---|
*/1 * * * * * | 每1s执行一次 |
* 1-5 * * * * | 第1分钟到第5分钟触发,触发时每秒执行一次 |
0 1-5 * * * * | 第1分钟到第5分钟的第0秒分别触发一次 |
0 */2 * * * * | 每隔2分钟执行一次 |
0 0 13 * * * | 每天13:00:00执行一次 |
* 1-5 * * * * | 第1分钟到第5分钟触发,触发时一直执行 |
0 0-5 14 * * * | 在每天下午2点到下午2:05期间的每1分钟触发一次 |
0 0 23 L * ? | 每月最后一天23:00:00执行一次 |
0 30 17 LW * ? | 每个月最后一个工作日的17:30:00触发任务一次 |
2.3 配置定时任务
SpringBoot在默认情况下使用一个线程来处理定时任务,其实这已经满足了绝大多数的需求。如果想要更改,可通过设置spring.task.scheduling.pool.size属性:
spring:
task:
scheduling:
thread-name-prefix: my-scheduling-
pool:
size: 3
关于SpringBoot的异步任务、定时任务就讲解到这里,欢迎大家在评论区留言讨论。