本片文章对异步线程池、异步异常处理做了个Demo
[TOC]
@Async
在Spring中,基于@Async
标注的方法,称之为 异步方法;这些方法将在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。在Spring Boot中,我们只需要通过使用@Async
注解就能简单的将原来的同步函数变为异步函数。
异步方法分为两种:
- 返回值为void
- 返回值为Future
对应的异常处理操作:
- void -> 异步异常处理类
AsyncUncaughtExceptionHandler
来捕获并处理 - Future
-> 在异步方法中 try...catch...(处理)
,然后将异常信息封装到AsyncResult
对象中返回
环境/版本一览:
- 开发工具:Intellij IDEA 2018.2.2
- springboot: 2.0.6.RELEASE
- jdk:1.8.0_171
- maven:3.3.9
1、pom.xml
1 | <dependencies> |
2、config
异步配置类,实现接口 AsyncConfigurer
。配置类上加@EnableAsync
开启异步功能。配置类中配置两部分内容:异步线程池(组件)和异步异常处理类(组件)。
当我们使用@Async时,SpringBoot如果判断出容器中有AsyncConfigurer
类型的配置组件,它就会在该组件中是否有Executor
类型的线程池组件,如果没有,则会报错。
1 | package com.fatal.config; |
3、component
1 | package com.fatal.component; |
4、Test
1 | package com.fatal; |
5、显示
- 访问
Chapter242ApplicationTests.testPool()
显示
- 访问
Chapter242ApplicationTests.testAsyncExceptionReturnVoid()
显示
- 访问
Chapter242ApplicationTests.testAsyncExceptionReturnFuture()
显示
打开 Task.asyncReturnFutureWithException
中Thread.sleep(10000);
注释
笔记
异步线程池的配置
上面我们通过使用ThreadPoolTaskExecutor
创建了一个线程池,同时设置了以下这些参数:
- corePoolSize 核心线程数10:线程池创建时候初始化的线程数
- maxPoolSize 最大线程数20:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
- queueCapacity 缓冲队列200:用来缓冲执行任务的队列
- keepAliveSeconds 允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
- threadNamePrefix 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
- rejectedExecutionHandler 线程池对拒绝任务的处理策略:这里采用了
CallerRunsPolicy
策略,当线程池没有处理能力的时候,该策略会直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务
Future
什么是Future类型?
Future
是 对 于具体的Runnable
或者Callable
任务的 执行结果进行取消、是否被取消、查询是否完成、获取结果的接口。必要时可以通过 get()
方法获取执行结果,该方法会 阻塞 直到任务返回结果。
它的接口定义如下:
1 | package java.util.concurrent; |
方法解析:
cancel 方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。
参数 mayInterruptIfRunning 表示是否允许取消正在执行却没有执行完毕的任务。
(true 表允许,false 表不允许)
如果 任务已经完成,则无论 mayInterruptIfRunning 为 true 还是 false,此方法肯定返回 false;即如果取消已经完成的任务一定取消失败;
如果 任务正在执行,若mayInterruptIfRunning 设置为 true,则返回 true(取消成功),若 mayInterruptIfRunning 设置为 false,则返回false(取消失败);
如果 任务还没有执行,则无论 mayInterruptIfRunning 为 true 还是 false,肯定返回 true;即如果取消已经完成的任务一定取消成功。
isCancelled 方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
isDone 方法表示任务是否已经完成,若任务完成,则返回 true;
get() 方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;
get(long timeout, TimeUnit unit) 用来获取执行结果,如果在指定时间内,还没获取到结果,就直接抛出
TimeoutException
,或者其他异常(具体看源码)。
也就是说Future提供了三种功能:
- 判断任务是否完成;
- 能够中断任务;
- 能够获取任务执行结果。
参考资料
Spring Boot系列二 Spring @Async异步线程池用法总结
Spring Boot使用@Async实现异步调用:自定义线程池
总结
步骤:
- 配置类(加
@EnableAsync
)配置 异步线程池、异步异常处理类 - 在指定方法上加
@Async
即可
SpringBoot
的知识已经有前辈在我们之前探索了。比较喜欢的博主有:唐亚峰 | Battcn、方志朋的专栏、程序猿DD、纯洁的微笑。对这门技术感兴趣的可以去他们的博客逛逛。谢谢他们的分享~~
以上文章是我用来学习的Demo
,都是基于 SpringBoot2.x
版本。
源码地址: https://github.com/ynfatal/springboot2-learning/tree/master/chapter/24_2