|
1 | 1 | [[features.task-execution-and-scheduling]]
|
2 | 2 | = Task Execution and Scheduling
|
3 | 3 |
|
4 |
| -In the absence of an `Executor` bean in the context, Spring Boot auto-configures an `AsyncTaskExecutor`. |
5 |
| -When virtual threads are enabled (using Java 21+ and configprop:spring.threads.virtual.enabled[] set to `true`) this will be a `SimpleAsyncTaskExecutor` that uses virtual threads. |
6 |
| -Otherwise, it will be a `ThreadPoolTaskExecutor` with sensible defaults. |
7 |
| -In either case, the auto-configured executor will be automatically used for: |
| 4 | +* if there is NO `Executor` bean | context -> Spring Boot auto-configures an `AsyncTaskExecutor` |
| 5 | + ** 👀if virtual threads are enabled -> `AsyncTaskExecutor` -- will be a -- `SimpleAsyncTaskExecutor` / uses virtual threads 👀 |
| 6 | + *** way to enable virtual threads |
| 7 | + **** use Java v21+ & |
| 8 | + **** `spring.threads.virtual.enabled=true` . |
| 9 | + ** 👀by default, `AsyncTaskExecutor` -- will be a -- `ThreadPoolTaskExecutor` / sensible defaults 👀 |
| 10 | + *** by default, thread pool uses 8 core threads |
| 11 | + **** / -- can, according to the load -- |
| 12 | + ***** grow |
| 13 | + ***** shrink |
| 14 | + ****** == if the demand for threads decreases (== tasks complete) -> the thread pool reclaims idle threads -- after a -- certain period of time (by default, 60s) |
| 15 | + **** if you want to customize it -> specify `spring.task.execution` |
8 | 16 |
|
9 |
| -- asynchronous task execution (`@EnableAsync`) |
10 |
| -- Spring for GraphQL's asynchronous handling of `Callable` return values from controller methods |
11 |
| -- Spring MVC's asynchronous request processing |
12 |
| -- Spring WebFlux's blocking execution support |
| 17 | + [configprops,yaml] |
| 18 | + ---- |
| 19 | + spring: |
| 20 | + task: |
| 21 | + execution: |
| 22 | + pool: |
| 23 | + # if the queue is full (100 tasks) -> thread pool -- increases to -- maximum 16 threads |
| 24 | + max-size: 16 |
| 25 | + queue-capacity: 100 |
| 26 | + keep-alive: "10s" |
| 27 | + ---- |
13 | 28 |
|
14 |
| -[TIP] |
15 |
| -==== |
16 |
| -If you have defined a custom `Executor` in the context, both regular task execution (that is `@EnableAsync`) and Spring for GraphQL will use it. |
17 |
| -However, the Spring MVC and Spring WebFlux support will only use it if it is an `AsyncTaskExecutor` implementation (named `applicationTaskExecutor`). |
18 |
| -Depending on your target arrangement, you could change your `Executor` into an `AsyncTaskExecutor` or define both an `AsyncTaskExecutor` and an `AsyncConfigurer` wrapping your custom `Executor`. |
| 29 | + ** `AsyncTaskExecutor` is used for |
| 30 | + *** asynchronous task execution |
| 31 | + **** == `@EnableAsync` |
| 32 | + *** Spring for GraphQL's asynchronous handling of `Callable` return values -- from -- controller methods |
| 33 | + *** Spring MVC's asynchronous request processing |
| 34 | + *** Spring WebFlux's blocking execution support |
| 35 | +* if you have defined a custom `Executor` | context -> it will be used by |
| 36 | + ** regular task execution (== `@EnableAsync`) |
| 37 | + ** Spring for GraphQL |
| 38 | + ** if it's an `AsyncTaskExecutor` implementation (named `applicationTaskExecutor`) |
| 39 | + *** -> ALSO used by |
| 40 | + **** Spring MVC |
| 41 | + **** Spring WebFlux |
| 42 | + *** coexistence of `Executor` & `AsyncTaskExecutor` -- depends on -- your target arrangement |
| 43 | + **** `Executor` -- can be changed into an -- `AsyncTaskExecutor` |
| 44 | + **** both an `AsyncTaskExecutor` and an `AsyncConfigurer` / wrap your custom `Executor` |
| 45 | +* auto-configured `ThreadPoolTaskExecutorBuilder` |
| 46 | + ** allows |
| 47 | + *** creating instances / reproduce what the auto-configuration does by default |
| 48 | +* if scheduler needs to be associated -- with -- scheduled task execution -> it's auto-configured |
| 49 | + ** _Example for this association:_ use `@EnableScheduling` |
| 50 | + ** if virtual threads are enabled -> scheduler -- will be a -- `SimpleAsyncTaskScheduler` / |
| 51 | + *** uses virtual threads |
| 52 | + *** ignore any pooling related properties |
| 53 | + ** by default, scheduler -- will be a -- `ThreadPoolTaskScheduler` / sensible defaults |
| 54 | + *** 1 thread by default |
| 55 | + *** if you want to customize it -> specify `spring.task.scheduling` |
19 | 56 |
|
20 |
| -The auto-configured `ThreadPoolTaskExecutorBuilder` allows you to easily create instances that reproduce what the auto-configuration does by default. |
21 |
| -==== |
| 57 | + [configprops,yaml] |
| 58 | + ---- |
| 59 | + spring: |
| 60 | + task: |
| 61 | + scheduling: |
| 62 | + thread-name-prefix: "scheduling-" |
| 63 | + pool: |
| 64 | + size: 2 |
| 65 | + ---- |
22 | 66 |
|
23 |
| -When a `ThreadPoolTaskExecutor` is auto-configured, the thread pool uses 8 core threads that can grow and shrink according to the load. |
24 |
| -Those default settings can be fine-tuned using the `spring.task.execution` namespace, as shown in the following example: |
25 |
| - |
26 |
| -[configprops,yaml] |
27 |
| ----- |
28 |
| -spring: |
29 |
| - task: |
30 |
| - execution: |
31 |
| - pool: |
32 |
| - max-size: 16 |
33 |
| - queue-capacity: 100 |
34 |
| - keep-alive: "10s" |
35 |
| ----- |
36 |
| - |
37 |
| -This changes the thread pool to use a bounded queue so that when the queue is full (100 tasks), the thread pool increases to maximum 16 threads. |
38 |
| -Shrinking of the pool is more aggressive as threads are reclaimed when they are idle for 10 seconds (rather than 60 seconds by default). |
39 |
| - |
40 |
| -A scheduler can also be auto-configured if it needs to be associated with scheduled task execution (using `@EnableScheduling` for instance). |
41 |
| - |
42 |
| -If virtual threads are enabled (using Java 21+ and configprop:spring.threads.virtual.enabled[] set to `true`) this will be a `SimpleAsyncTaskScheduler` that uses virtual threads. |
43 |
| -This `SimpleAsyncTaskScheduler` will ignore any pooling related properties. |
44 |
| - |
45 |
| -If virtual threads are not enabled, it will be a `ThreadPoolTaskScheduler` with sensible defaults. |
46 |
| -The `ThreadPoolTaskScheduler` uses one thread by default and its settings can be fine-tuned using the `spring.task.scheduling` namespace, as shown in the following example: |
47 |
| - |
48 |
| -[configprops,yaml] |
49 |
| ----- |
50 |
| -spring: |
51 |
| - task: |
52 |
| - scheduling: |
53 |
| - thread-name-prefix: "scheduling-" |
54 |
| - pool: |
55 |
| - size: 2 |
56 |
| ----- |
57 |
| - |
58 |
| -A `ThreadPoolTaskExecutorBuilder` bean, a `SimpleAsyncTaskExecutorBuilder` bean, a `ThreadPoolTaskSchedulerBuilder` bean and a `SimpleAsyncTaskSchedulerBuilder` are made available in the context if a custom executor or scheduler needs to be created. |
59 |
| -The `SimpleAsyncTaskExecutorBuilder` and `SimpleAsyncTaskSchedulerBuilder` beans are auto-configured to use virtual threads if they are enabled (using Java 21+ and configprop:spring.threads.virtual.enabled[] set to `true`). |
| 67 | +* if a custom executor OR scheduler needs to be created -> available | context |
| 68 | + ** `ThreadPoolTaskExecutorBuilder` bean |
| 69 | + ** `SimpleAsyncTaskExecutorBuilder` bean |
| 70 | + ** `ThreadPoolTaskSchedulerBuilder` bean |
| 71 | + ** `SimpleAsyncTaskSchedulerBuilder` bean |
| 72 | +* if virtual threads are enabled -> beans / auto-configured -- to use -- them |
| 73 | + ** `SimpleAsyncTaskExecutorBuilder` |
| 74 | + ** `SimpleAsyncTaskSchedulerBuilder` |
0 commit comments