Spring异步执行提供了一层抽象,用于屏蔽Java SE5, Java SE6, JavaEE等环境之间的差异,会执行实现了TaskExecutor接口的任务。
Spring预先实现了一系列TaskExecutor,一般情形下不必自己去实现:
SimpleAsyncTaskExecutor:不会重用任何一个线程,每次调用都会创建一个新的线程,但是支持一个并发度的限制,超过这个线程的调用将会被阻塞,除非低于这个限制才会被继续调用。
SyncTaskExecutor:任何调用都不会被异步执行,都会使用调用者的线程执行任务,主要的场景是多线程执行不是必须的,如单元测试
ConcurrentTaskExecutor:是java.util.concurrent.Executor的一个适配对象,ThreadPoolTaskExecutor是它的一个替代,它暴露一个Executor作为配置参数。更倾向于使用ConcurrentTaskExecutor,如果ThreadPoolTaskExecutor对于你的需求不够灵活,ConcurrentTaskExecutor是一个替代。
SimpleThreadPoolTaskExecutor:它的实现实际是Quartz SimpleThreadPoolTaskExecutor的一个子类,能够监听Spring生命周期的回调。典型的使用,就是你需要在Quartz组件和非Quartz组件之间需要共享的线程池。
ThreadPoolTaskExecutor:是最广泛使用的一个实现,它可以使用ThreadPoolExecutor作为一个配置参数,然后会被包装为TaskExecutor.如果你需要适配不同类型的java.util.concurrent.Executor,推荐使用ConcurrentTaskExecutor.
WorkManagerTaskExecutor: CommonJ是BEA和IBM联合确立的一些列规范,这个规范不是JavaEE标准,而是跨BEA和IBM应用服务器的实现。使用CommonJ WorkManager作为背后的实现,对于核心类而言在Spring Context中设置CommonJ WorkManager的引用是很方便的。与SimpleThreadPoolTaskExecutor相似,这个类实现了WorkManager接口,因此可以直接作为WorkManager使用。
Spring异步的使用:
1.无返回值使用:
public void display(String message) {
log.info(message);
}
调用:
asyncTask.display("hello world");
2.有返回值
public Future<String> getFutureMessage(String message) {
try {
TimeUnit.SECONDS.sleep(3L);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new AsyncResult<>("future: " + message + " ***** " + Thread.currentThread().getName());
}
调用:
Future<String> str = asyncTask.getFutureMessage("haha");
3.使用ListenableFuture
public ListenableFuture<String> getListenableFuture(String message) {
try {
TimeUnit.SECONDS.sleep(3L);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new AsyncResult<>("listenable future: " + message + " ***** " + Thread.currentThread().getName());
}
调用:
ListenableFuture<String> str2 = asyncTask.getListenableFuture("haha");
str2.addCallback(new MySuccessCallback(), new MyFailureCallback());
4.使用CompletableFuture
public CompletableFuture<String> getCompletableFuture(String message) {
try {
TimeUnit.SECONDS.sleep(3L);
} catch (InterruptedException e) {
e.printStackTrace();
}
return CompletableFuture.completedFuture("completable future: " + message + " ****** " + Thread.currentThread().getName());
}
调用:
CompletableFuture<String> completableFuture = asyncTask.getCompletableFuture("hello");
异步使用指定的executor:
-
使用名字
-
@Async("executor")
-
-
使用@Qualifier
-
@Qualifier("executor")
-
使用注意点
-
Spring的线程池和JDK自带的线程池存在一定的差异,使用的时候应当注意
-
异步的时候注意返回值
-
异步的时候必须注意异常的处理