任务执行和调度

如果上下文环境中不存在 `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将忽略任何与池相关的属性。

如果未启用虚拟线程,它将是一个具有合理默认值的ThreadPoolTaskSchedulerThreadPoolTaskScheduler默认使用一个线程,其设置可以使用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),则SimpleAsyncTaskExecutorBuilderSimpleAsyncTaskSchedulerBuilder bean将自动配置为使用虚拟线程。