0 day streak
java / intermediate
Snippet

Configuring ThreadPoolTaskExecutor with Custom Rejection Execution Policies

ThreadPoolTaskExecutor wraps Java's ThreadPoolExecutor with Spring lifecycle management. Configuring a bounded queue capacity alongside CallerRunsPolicy provides backpressure when thread capacity is exceeded: instead of dropping tasks or crashing with RejectedExecutionException, the submitting thread executes the task itself, naturally slowing down incoming ingestion.

snippet.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Configuration
@EnableAsync
public class AsyncExecutionConfig {
@Bean(name = "eventProcessingExecutor")
public Executor eventProcessingExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(4);
executor.setMaxPoolSize(16);
executor.setQueueCapacity(50);
executor.setThreadNamePrefix("EventWorker-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(30);
executor.initialize();
return executor;
}
}
@Service
public class EventPublisher {
@Async("eventProcessingExecutor")
public CompletableFuture<String> processEventPayload(String eventId) {
return CompletableFuture.completedFuture("Processed: " + eventId);
}
}
spring
Breakdown
1
executor.setQueueCapacity(50);
Sets the internal blocking queue capacity before the executor spawns additional threads up to maxPoolSize.
2
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
Applies a backpressure policy where saturated queues cause tasks to run on the caller thread rather than being discarded.
3
executor.setWaitForTasksToCompleteOnShutdown(true);
Ensures active background tasks finish execution before the Spring container fully terminates.