@Async指定的执行器是否适用于CompletableFuture.supplyAsync(供应商)



我有一个执行器

@Bean("someExecutor")
public Executor someExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("AsyncMethod-");
executor.initialize();
return executor;
}

以及异步方法。

@Async("someExecutor")
public Future<List<String>> someMethod(){
return CompletableFuture.supplyAsync(() -> {
//long time job
return listGeneratedByLongTimeJob;
});
}

Spring会为someMethod使用someExecutor吗?如何?

我知道supplyAsync(供应商(的重载方法是supplyAnc(供应商,执行器(,下面的代码怎么样?

@Autowired("someExecutor")
private Executor executor;
@Async()
public Future<List<String>> someMethod(){
return CompletableFuture.supplyAsync(() -> {
//long time job
return listGeneratedByLongTimeJob;
}, executor);
}

谢谢。

好吧,这需要一段时间才能弄清楚,在进入两个场景之前,我们需要讨论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]

在这种情况下CCD_ 5由CCD_,supplyAsync()中的供应商由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来实际运行这些async方法,但我们在配置中使用@EnableAsyncdocs 覆盖了someExecutor

默认情况下,Spring将搜索关联的线程池定义:上下文中的唯一TaskExecutitor bean,或者名为"taskExecutitor"的Executitor bean。如果两者都不可解析,那么将使用SimpleAsyncTaskExecutor来处理异步方法调用。

注意:如果您在配置类中没有@EnableAsync,您将得到不同的结果,我将在gitHub中上传此代码,并在此处添加链接

相关内容

最新更新