请直接看原文:
Spring @Async 注解的使用以及原理(一)_@async注解-CSDN博客
Spring @Async 注解的使用以及原理(二)_@-CSDN博客
--------------------------------------------------------------------------------------------------------------------------------
上面源码已经讲的很详细了, 我下面只做几个总结就好了.
Spring 已经实现的线程池
1. SimpleAsyncTaskExecutor:不是真的线程池,这个类不重用线程,默认每次调用都会创建一个新的线程。
2. SyncTaskExecutor:这个类没有实现异步调用,只是一个同步操作。只适用于不需要多线程的地方。
3. ConcurrentTaskExecutor:Executor的适配类,不推荐使用。如果ThreadPoolTaskExecutor不满足要求时,才用考虑使用这个类。
4. SimpleThreadPoolTaskExecutor:是Quartz的SimpleThreadPool的类。线程池同时被quartz和非quartz使用,才需要使用此类。
5. ThreadPoolTaskExecutor :最常使用,推荐。 其实质是对java.util.concurrent.ThreadPoolExecutor的包装。
@Async注解一般用在类的方法上,如果用在类上,那么这个类所有的方法都是异步执行的
看源码分析:
某某某通过委托实现@Async异步方法的调用。在invoke()方法中获取执行器executor,创建Callable异步线程任务,提交到执行器executor(对应的线程池)中执行。
@Async加在方法上有三种使用
1. 最简单的异步调用,返回值为void
2. 带参数的异步调用,异步方法可以传入参数
3. 存在返回值,常调用返回Future
/**
2 * 异常调用返回Future
3 * 对于返回值是Future,不会被AsyncUncaughtExceptionHandler处理,需要我们在方法中捕获异常并处理
4 * 或者在调用方在调用Futrue.get时捕获异常进行处理
5 *
6 * @param i
7 * @return
8 */
9 @Async
10 public Future asyncInvokeReturnFuture(int i) {
11 log.info("asyncInvokeReturnFuture, parementer={}", i);
12 Future future;
13 try {
14 Thread.sleep(1000 * 1);
15 future = new AsyncResult("success:" + i);
16 throw new IllegalArgumentException("a");
17 } catch (InterruptedException e) {
18 future = new AsyncResult("error");
19 } catch(IllegalArgumentException e){
20 future = new AsyncResult("error-IllegalArgumentException");
21 }
22 return future;
23 }
看源码分析:@Async和@EnableAsync注解实现方法异步调用底层是通过AOP和线程池实现的。
通过委托实现@Async异步方法的调用。在invoke()方法中获取执行器executor,创建Callable异步线程任务,提交到执行器executor(对应的线程池)中执行。
因此要注意:
1.所使用的@Async注解方法的类对象应该是Spring容器管理的bean对象
2.不能用本类方法调本类有@Async注解的方法,相当于this,会使代理失效,会使@Async注解失效
不同类中的加了@Async注解的方法,可以相互调用,调一个加了@Async注解的方法就相当于新开了一个线程去执行这个方法.仅此而已