好吧,这需要一段时间才能弄清楚,在进入两个场景之前,我们需要讨论一下ForkJoinPool
来自 java.util.concurrent.CompletableFuture 文档
所有没有显式 Executor 参数的异步方法都使用 ForkJoinPool.commonPool()执行(除非它不支持至少两个并行级别,在这种情况下,会创建一个新线程来运行每个任务)。为了简化监控、调试和跟踪,所有生成的异步任务都是标记接口 CompletableFuture.AsynchronousCompletionTask 的实例。
因此,当您每次调用时CompletableFuture.supplyAsync(Supplier s),供应商将由ForkJoinPool线程执行,现在让我们开始案例 1
情况1:
为了清楚起见,我添加了一些sysout语句来打印线程名称
@Async("someExecutor")
public Future<String> asyncService() {
System.out.println();
System.out.println(Thread.currentThread().getName()+" - "+Thread.currentThread().getThreadGroup());
System.out.println();
return CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread().getName()+" - "+Thread.currentThread().getThreadGroup());
return "hello";
});
}
输出:
AsyncMethod-1 - java.lang.ThreadGroup[name=main,maxpri=10]
ForkJoinPool.commonPool-worker-1 - java.lang.ThreadGroup[name=main,maxpri=10]
在这种情况下asyncService(),由AsyncMethod-1线程执行,供应商 insupplyAsync()由ForkJoinPool
案例2:
@Autowired
private Executor someExecutor;
@Async
public Future<String> asyncService() {
System.out.println();
System.out.println(Thread.currentThread().getName()+" - "+Thread.currentThread().getThreadGroup());
System.out.println();
return CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread().getName()+" - "+Thread.currentThread().getThreadGroup());
return "hello";
},someExecutor);
}
输出:
AsyncMethod-1 - java.lang.ThreadGroup[name=main,maxpri=10]
AsyncMethod-2 - java.lang.ThreadGroup[name=main,maxpri=10]
在第二种情况下asyncService(),方法和供应商supplyAsync()都使用来自someExecutor pool
默认情况下,Spring 使用 SimpleAsyncTaskExecutor 来实际运行这些方法,但我们在 config using docsasync中覆盖了它someExecutor@EnableAsync
默认情况下,Spring 将搜索关联的线程池定义:要么是上下文中唯一的 TaskExecutor bean,要么是名为“taskExecutor”的 Executor bean。如果两者都无法解析,则将使用 SimpleAsyncTaskExecutor 来处理异步方法调用。
注意:如果您没有@EnableAsync配置类,您将得到不同的结果,我将在 gitHub 中上传此代码并在此处添加链接