任务执行和调度
如果上下文环境中不存在 `Executor` bean,Spring Boot 会自动配置一个 `AsyncTaskExecutor`。当启用虚拟线程时(使用 Java 21+ 并将 `spring.threads.virtual.enabled` 设置为 `true`),这将是一个使用虚拟线程的 `SimpleAsyncTaskExecutor`。否则,它将是一个具有合理默认值的 `ThreadPoolTaskExecutor`。在这两种情况下,自动配置的执行器都将自动用于:
-
异步任务执行 (
@EnableAsync
) -
Spring for GraphQL 对来自控制器方法的 `Callable` 返回值的异步处理
-
Spring MVC 的异步请求处理
-
Spring WebFlux 的阻塞执行支持
如果已在上下文中定义了自定义 `Executor`,则常规任务执行(即 `@EnableAsync`)和 Spring for GraphQL 都将使用它。但是,Spring MVC 和 Spring WebFlux 支持只有在它是 `AsyncTaskExecutor` 实现(命名为 `applicationTaskExecutor`)时才会使用它。根据您的目标安排,您可以将 `Executor` 更改为 `AsyncTaskExecutor` 或同时定义 `AsyncTaskExecutor` 和 `AsyncConfigurer` 来包装您的自定义 `Executor`。 自动配置的 `ThreadPoolTaskExecutorBuilder` 允许您轻松创建可以重现自动配置默认行为的实例。 |
当自动配置 `ThreadPoolTaskExecutor` 时,线程池使用 8 个核心线程,这些线程可以根据负载进行增长和缩小。这些默认设置可以使用 `spring.task.execution` 命名空间进行微调,如下例所示:
-
属性
-
YAML
spring.task.execution.pool.max-size=16
spring.task.execution.pool.queue-capacity=100
spring.task.execution.pool.keep-alive=10s
spring:
task:
execution:
pool:
max-size: 16
queue-capacity: 100
keep-alive: "10s"
这将线程池更改为使用有界队列,以便当队列已满(100 个任务)时,线程池增加到最大 16 个线程。池的缩小更积极,因为当线程空闲 10 秒(而不是默认的 60 秒)时,线程将被回收。
如果需要将调度程序与计划的任务执行关联(例如使用 `@EnableScheduling`),也可以自动配置调度程序。
如果启用了虚拟线程(使用 Java 21+ 并将spring.threads.virtual.enabled
设置为true
),这将是一个使用虚拟线程的SimpleAsyncTaskScheduler
。此SimpleAsyncTaskScheduler
将忽略任何与池相关的属性。
如果未启用虚拟线程,它将是一个具有合理默认值的ThreadPoolTaskScheduler
。ThreadPoolTaskScheduler
默认使用一个线程,其设置可以使用spring.task.scheduling
命名空间进行微调,如下例所示。
-
属性
-
YAML
spring.task.scheduling.thread-name-prefix=scheduling-
spring.task.scheduling.pool.size=2
spring:
task:
scheduling:
thread-name-prefix: "scheduling-"
pool:
size: 2
如果需要创建自定义执行器或调度器,则上下文中将提供ThreadPoolTaskExecutorBuilder
bean、SimpleAsyncTaskExecutorBuilder
bean、ThreadPoolTaskSchedulerBuilder
bean和SimpleAsyncTaskSchedulerBuilder
bean。如果启用了虚拟线程(使用 Java 21+ 并将spring.threads.virtual.enabled
设置为true
),则SimpleAsyncTaskExecutorBuilder
和SimpleAsyncTaskSchedulerBuilder
bean将自动配置为使用虚拟线程。