我有一个执行器
@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
方法,但我们在配置中使用@EnableAsync
docs 覆盖了someExecutor
默认情况下,Spring将搜索关联的线程池定义:上下文中的唯一TaskExecutitor bean,或者名为"taskExecutitor"的Executitor bean。如果两者都不可解析,那么将使用SimpleAsyncTaskExecutor来处理异步方法调用。
注意:如果您在配置类中没有@EnableAsync
,您将得到不同的结果,我将在gitHub中上传此代码,并在此处添加链接