4040 * bean and can be injected whenever a {@link TaskExecutor} is needed.
4141 *
4242 * @author Stephane Nicoll
43+ * @author Filip Hrisafov
4344 * @since 2.1.0
4445 */
4546public class TaskExecutorBuilder {
@@ -56,6 +57,10 @@ public class TaskExecutorBuilder {
5657
5758 private final String threadNamePrefix ;
5859
60+ private final Duration awaitTermination ;
61+
62+ private final Boolean waitForTasksToCompleteOnShutdown ;
63+
5964 private final TaskDecorator taskDecorator ;
6065
6166 private final Set <TaskExecutorCustomizer > customizers ;
@@ -67,20 +72,25 @@ public TaskExecutorBuilder() {
6772 this .allowCoreThreadTimeOut = null ;
6873 this .keepAlive = null ;
6974 this .threadNamePrefix = null ;
75+ this .awaitTermination = null ;
76+ this .waitForTasksToCompleteOnShutdown = null ;
7077 this .taskDecorator = null ;
7178 this .customizers = null ;
7279 }
7380
7481 private TaskExecutorBuilder (Integer queueCapacity , Integer corePoolSize ,
7582 Integer maxPoolSize , Boolean allowCoreThreadTimeOut , Duration keepAlive ,
76- String threadNamePrefix , TaskDecorator taskDecorator ,
83+ String threadNamePrefix , Duration awaitTermination ,
84+ Boolean waitForTasksToCompleteOnShutdown , TaskDecorator taskDecorator ,
7785 Set <TaskExecutorCustomizer > customizers ) {
7886 this .queueCapacity = queueCapacity ;
7987 this .corePoolSize = corePoolSize ;
8088 this .maxPoolSize = maxPoolSize ;
8189 this .allowCoreThreadTimeOut = allowCoreThreadTimeOut ;
8290 this .keepAlive = keepAlive ;
8391 this .threadNamePrefix = threadNamePrefix ;
92+ this .awaitTermination = awaitTermination ;
93+ this .waitForTasksToCompleteOnShutdown = waitForTasksToCompleteOnShutdown ;
8494 this .taskDecorator = taskDecorator ;
8595 this .customizers = customizers ;
8696 }
@@ -94,6 +104,7 @@ private TaskExecutorBuilder(Integer queueCapacity, Integer corePoolSize,
94104 public TaskExecutorBuilder queueCapacity (int queueCapacity ) {
95105 return new TaskExecutorBuilder (queueCapacity , this .corePoolSize , this .maxPoolSize ,
96106 this .allowCoreThreadTimeOut , this .keepAlive , this .threadNamePrefix ,
107+ this .awaitTermination , this .waitForTasksToCompleteOnShutdown ,
97108 this .taskDecorator , this .customizers );
98109 }
99110
@@ -109,6 +120,7 @@ public TaskExecutorBuilder queueCapacity(int queueCapacity) {
109120 public TaskExecutorBuilder corePoolSize (int corePoolSize ) {
110121 return new TaskExecutorBuilder (this .queueCapacity , corePoolSize , this .maxPoolSize ,
111122 this .allowCoreThreadTimeOut , this .keepAlive , this .threadNamePrefix ,
123+ this .awaitTermination , this .waitForTasksToCompleteOnShutdown ,
112124 this .taskDecorator , this .customizers );
113125 }
114126
@@ -124,6 +136,7 @@ public TaskExecutorBuilder corePoolSize(int corePoolSize) {
124136 public TaskExecutorBuilder maxPoolSize (int maxPoolSize ) {
125137 return new TaskExecutorBuilder (this .queueCapacity , this .corePoolSize , maxPoolSize ,
126138 this .allowCoreThreadTimeOut , this .keepAlive , this .threadNamePrefix ,
139+ this .awaitTermination , this .waitForTasksToCompleteOnShutdown ,
127140 this .taskDecorator , this .customizers );
128141 }
129142
@@ -136,7 +149,9 @@ public TaskExecutorBuilder maxPoolSize(int maxPoolSize) {
136149 public TaskExecutorBuilder allowCoreThreadTimeOut (boolean allowCoreThreadTimeOut ) {
137150 return new TaskExecutorBuilder (this .queueCapacity , this .corePoolSize ,
138151 this .maxPoolSize , allowCoreThreadTimeOut , this .keepAlive ,
139- this .threadNamePrefix , this .taskDecorator , this .customizers );
152+ this .threadNamePrefix , this .awaitTermination ,
153+ this .waitForTasksToCompleteOnShutdown , this .taskDecorator ,
154+ this .customizers );
140155 }
141156
142157 /**
@@ -147,7 +162,9 @@ public TaskExecutorBuilder allowCoreThreadTimeOut(boolean allowCoreThreadTimeOut
147162 public TaskExecutorBuilder keepAlive (Duration keepAlive ) {
148163 return new TaskExecutorBuilder (this .queueCapacity , this .corePoolSize ,
149164 this .maxPoolSize , this .allowCoreThreadTimeOut , keepAlive ,
150- this .threadNamePrefix , this .taskDecorator , this .customizers );
165+ this .threadNamePrefix , this .awaitTermination ,
166+ this .waitForTasksToCompleteOnShutdown , this .taskDecorator ,
167+ this .customizers );
151168 }
152169
153170 /**
@@ -158,7 +175,41 @@ public TaskExecutorBuilder keepAlive(Duration keepAlive) {
158175 public TaskExecutorBuilder threadNamePrefix (String threadNamePrefix ) {
159176 return new TaskExecutorBuilder (this .queueCapacity , this .corePoolSize ,
160177 this .maxPoolSize , this .allowCoreThreadTimeOut , this .keepAlive ,
161- threadNamePrefix , this .taskDecorator , this .customizers );
178+ threadNamePrefix , this .awaitTermination ,
179+ this .waitForTasksToCompleteOnShutdown , this .taskDecorator ,
180+ this .customizers );
181+ }
182+
183+ /**
184+ * Set the maximum number of time that the executor is supposed to block on shutdown
185+ * in order to wait for remaining tasks to complete their execution before the rest of
186+ * the container continues to shut down. This is particularly useful if your remaining
187+ * tasks are likely to need access to other resources that are also managed by the
188+ * container.
189+ * @param awaitTermination the await termination to set
190+ * @return a new builder instance
191+ */
192+ public TaskExecutorBuilder awaitTermination (Duration awaitTermination ) {
193+ return new TaskExecutorBuilder (this .queueCapacity , this .corePoolSize ,
194+ this .maxPoolSize , this .allowCoreThreadTimeOut , this .keepAlive ,
195+ this .threadNamePrefix , awaitTermination ,
196+ this .waitForTasksToCompleteOnShutdown , this .taskDecorator ,
197+ this .customizers );
198+ }
199+
200+ /**
201+ * Set whether the executor should wait for scheduled tasks to complete on shutdown,
202+ * not interrupting running tasks and executing all tasks in the queue.
203+ * @param waitForTasksToCompleteOnShutdown if executor needs to wait for the tasks to
204+ * complete on shutdown
205+ * @return a new builder instance
206+ */
207+ public TaskExecutorBuilder waitForTasksToCompleteOnShutdown (
208+ boolean waitForTasksToCompleteOnShutdown ) {
209+ return new TaskExecutorBuilder (this .queueCapacity , this .corePoolSize ,
210+ this .maxPoolSize , this .allowCoreThreadTimeOut , this .keepAlive ,
211+ this .threadNamePrefix , this .awaitTermination ,
212+ waitForTasksToCompleteOnShutdown , this .taskDecorator , this .customizers );
162213 }
163214
164215 /**
@@ -169,7 +220,8 @@ public TaskExecutorBuilder threadNamePrefix(String threadNamePrefix) {
169220 public TaskExecutorBuilder taskDecorator (TaskDecorator taskDecorator ) {
170221 return new TaskExecutorBuilder (this .queueCapacity , this .corePoolSize ,
171222 this .maxPoolSize , this .allowCoreThreadTimeOut , this .keepAlive ,
172- this .threadNamePrefix , taskDecorator , this .customizers );
223+ this .threadNamePrefix , this .awaitTermination ,
224+ this .waitForTasksToCompleteOnShutdown , taskDecorator , this .customizers );
173225 }
174226
175227 /**
@@ -199,7 +251,9 @@ public TaskExecutorBuilder customizers(Iterable<TaskExecutorCustomizer> customiz
199251 Assert .notNull (customizers , "Customizers must not be null" );
200252 return new TaskExecutorBuilder (this .queueCapacity , this .corePoolSize ,
201253 this .maxPoolSize , this .allowCoreThreadTimeOut , this .keepAlive ,
202- this .threadNamePrefix , this .taskDecorator , append (null , customizers ));
254+ this .threadNamePrefix , this .awaitTermination ,
255+ this .waitForTasksToCompleteOnShutdown , this .taskDecorator ,
256+ append (null , customizers ));
203257 }
204258
205259 /**
@@ -229,7 +283,8 @@ public TaskExecutorBuilder additionalCustomizers(
229283 Assert .notNull (customizers , "Customizers must not be null" );
230284 return new TaskExecutorBuilder (this .queueCapacity , this .corePoolSize ,
231285 this .maxPoolSize , this .allowCoreThreadTimeOut , this .keepAlive ,
232- this .threadNamePrefix , this .taskDecorator ,
286+ this .threadNamePrefix , this .awaitTermination ,
287+ this .waitForTasksToCompleteOnShutdown , this .taskDecorator ,
233288 append (this .customizers , customizers ));
234289 }
235290
@@ -275,6 +330,10 @@ public <T extends ThreadPoolTaskExecutor> T configure(T taskExecutor) {
275330 map .from (this .allowCoreThreadTimeOut ).to (taskExecutor ::setAllowCoreThreadTimeOut );
276331 map .from (this .threadNamePrefix ).whenHasText ()
277332 .to (taskExecutor ::setThreadNamePrefix );
333+ map .from (this .awaitTermination ).asInt (Duration ::getSeconds )
334+ .to (taskExecutor ::setAwaitTerminationSeconds );
335+ map .from (this .waitForTasksToCompleteOnShutdown )
336+ .to (taskExecutor ::setWaitForTasksToCompleteOnShutdown );
278337 map .from (this .taskDecorator ).to (taskExecutor ::setTaskDecorator );
279338 if (!CollectionUtils .isEmpty (this .customizers )) {
280339 this .customizers .forEach ((customizer ) -> customizer .customize (taskExecutor ));
0 commit comments