使用@Async可以帮助我们快速将@Async标注的方法在一个异步线程池中处理
如何开启@Async
需要一个注解 @EnableAsync 开启 @Async 的功能,可以放在 Application 上,也可以放其他配置文件上。
@SpringBootApplication(scanBasePackages = "zmx.study")
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@EnableAsync
@Configuration
@Slf4j
public class AsyncConfig implements AsyncConfigurer {
// ...
}
@Async使用
将@Async标注一个方法中即可,有两个条件:
- 它必须仅适用于 public 方法,返回值只能是 void 或者 Future
- 不能在同一个类中调用异步方法
@Async
public void doSomething(String arg1) {
log.info("doSomething --{}-- >{}", Thread.currentThread().getName(), arg1);
throw new RuntimeException("test");
}
@Async如何将标注的方法放到线程池中的?
- 默认情况下找唯一的 org.springframework.core.task.TaskExecutor,或者一个 Bean 的 Name 为 taskExecutor 的 java.util.concurrent.Executor 作为执行任务的线程池。(ThreadPoolTaskExecutor就是TaskExecutor类型的线程池)
- 如果都没有的话,会创建 SimpleAsyncTaskExecutor 线程池来处理异步方法调用
- @Async 注解支持一个 String 参数,来指定一个 Bean 的 Name,类型是 Executor 或 TaskExecutor,表示使用这个指定的线程池来执行这个异步任务。@Async("commonThreadPool")
异常的处理
@EnableAsync
@Configuration
@Slf4j
public class AsyncConfig implements AsyncConfigurer {
/**
* 可以不用实现,使用默认规则下的线程池
*
*/
/*@Override
public Executor getAsyncExecutor() {
return null;
}*/
/**
* 只能捕获无返回值的异步方法,有返回值的被主线程处理
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new MyAsyncExceptionHandler();
}
/***
* 处理异步方法中未捕获的异常
*
*/
class MyAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
log.info("Exception message - {}", throwable.getMessage());
log.info("Method name - {}", method.getName());
log.info("Parameter values - {}", Arrays.toString(obj));
if (throwable instanceof Exception) {
Exception exception = (Exception) throwable;
log.info("exception:{}", exception.getMessage());
}
throwable.printStackTrace();
}
}
}
网友评论