gpt4 book ai didi

java - @Async 指定的执行器是否为 CompletableFuture.supplyAsync(supplier) 工作?

转载 作者:行者123 更新时间:2023-11-30 10:08:41 24 4
gpt4 key购买 nike

我有一个执行者,

@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(supplier) 的重载方法是 supplyAsync(supplier, executor),下面的代码怎么样?

@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 docs

All async methods without an explicit Executor argument are performed using the ForkJoinPool.commonPool() (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task). To simplify monitoring, debugging, and tracking, all generated asynchronous tasks are instances of the marker interface 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 线程执行,并且,supplyAsync() 中的 supplier 由 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 池的线程

默认情况下,Spring 使用 SimpleAsyncTaskExecutor 来实际运行这些 async 方法,但我们使用 @EnableAsync docs 在配置中用 someExecutor 覆盖了它

By default, Spring will be searching for an associated thread pool definition: either a unique TaskExecutor bean in the context, or an Executor bean named "taskExecutor" otherwise. If neither of the two is resolvable, a SimpleAsyncTaskExecutor will be used to process async method invocations.

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

关于java - @Async 指定的执行器是否为 CompletableFuture.supplyAsync(supplier) 工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53662386/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com