英文:
Sprint boot async - does not use max-size
问题
这是你的内容的中文翻译:
我正在尝试使用Spring Boot的异步功能,但在使其按照我的需求工作方面遇到了一些问题。
这是我的应用程序yml配置:
spring:
task:
execution:
pool:
max-size: 100
queue-capacity: 5
keep-alive: "10s"
core-size: 10
应用程序类:
@SpringBootApplication
@EnableAsync
public class ServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
服务类:
for (int i=0; i<40; i++) {
CompletableFuture.runAsync(() -> {
try {
System.out.println("------------------开始线程------------------");
// 这里执行一些操作
System.out.println("------------------结束线程------------------");
} catch (Exception e) {
e.printStackTrace();
}
});
}
我期望看到System.out的输出会出现40次。中间的操作需要足够长的时间,我尝试添加Thread.sleep(),但我没有看到sysout的打印超过8次。我的配置有问题吗,还是它不按照我的期望工作?
英文:
I am trying out Spring Boot's Async feature, but I am having some trouble getting it to work as I need.
This is my application yml
spring:
task:
execution:
pool:
max-size: 100
queue-capacity: 5
keep-alive: "10s"
core-size: 10
Application class
@SpringBootApplication
@EnableAsync
public class ServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
Service class:
for (int i=0;i< 40; i++) {
CompletableFuture.runAsync(()-> {
try {
System.out.println("------------------Starting thread------------------");
//do some action here
System.out.println("------------------Ending thread------------------");
} catch (Exception e) {
e.printStackTrace();
}
});
}
I am expecting to see the System.out print out 40 times. The operations in between take long enough, and I have tried adding Thread.sleep(), but I do not see the sysouts printed more than 8 times. Is there something wrong with my config, or does it not work the way I expect?
答案1
得分: 0
Completable future 对 Spring 使用的线程池一无所知。
来自 runAsync()
方法的文档:
返回一个新的CompletableFuture,由在ForkJoinPool.commonPool()中运行给定操作之后异步完成的任务生成。参数:runnable - 在完成返回的CompletableFuture之前运行的操作 返回:新的CompletableFuture
因此,这些任务是在ForkJoinPool
上运行的,而不是Spring使用的执行程序。
关于Spring使用的执行程序与@EnableAsync的说明:
默认情况下,Spring将搜索与线程池定义相关的内容:上下文中的唯一TaskExecutor bean,或者名为"taskExecutor"的Executor bean。如果两者都无法解析,将使用SimpleAsyncTaskExecutor来处理异步方法调用。此外,具有void返回类型的带注释方法无法将任何异常传递回调用者。默认情况下,仅记录此类未捕获的异常。
您可以尝试自动装配该执行程序并将其作为参数传递给
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
返回一个新的CompletableFuture,由在运行给定操作之后在给定执行程序中异步完成的任务生成。参数:runnable - 在完成返回的CompletableFuture之前运行的操作 executor - 用于异步执行的执行程序
英文:
Completable future has no idea about the pool that is used by Spring.
From docs of runAsync()
method:
> Returns a new CompletableFuture that is asynchronously completed by a
> task running in the ForkJoinPool.commonPool() after it runs the given
> action. Params: runnable – the action to run before completing the
> returned CompletableFuture Returns: the new CompletableFuture
So, those tasks are being run on ForkJoinPool
, not on executor used by Spring.
About executor used by Spring with @EnableAsync:
> 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. Besides, annotated methods having a void return
> type cannot transmit any exception back to the caller. By default,
> such uncaught exceptions are only logged.
You could try autowire that executor and pass it as an argument to
<!-- language: java -->
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
> Returns a new CompletableFuture that is asynchronously completed by a
> task running in the given executor after it runs the given action.
> Params: runnable – the action to run before completing the returned
> CompletableFuture executor – the executor to use for asynchronous
> execution
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论