We need to run task in parallel so we are using spring @Async feature. To provide executor config we are creating a Executor bean.
@Bean(name = "async")
public Executor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(5);
executor.setThreadNamePrefix("MyExecutor-");
executor.initialize();
return executor;
}
As soon as the number of parallel task are reached beyond maxpoolSize + queue size the next task submission fails with rejectedExecutionexception.
To overcome this we have looked into caller Abort policy from source: https://www.baeldung.com/java-rejectedexecutionhandler which provides the facility that main thread itself run the task in case queue and thread are already full.
setting need for it is : executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
Q1. I need to understand that ThreadPoolTaskExecutor uses a LinkedBlocking queue , My expectation was that once max pool thread and queue size is full and occupied, main thread will get blocked while submitting a new task, But instead it is failing with RejectedException, even though a blocking queue is present in ThreadPoolTaskExecutor?
Q2. To overcome this how can we implement a blocking mechanism where the main doesn't get fail while submitting a new task nor run by itself (as in executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy())) but gets blocked for the space to available in queue to put task in the queue?
Blocking a main thread indefinitely can lead to dead lock scenarios. That is the reason for providing a handler for application users to decide what should be the behavior when thread pool queue capacity exceeds.
Various implementation of the required blocking behavior can be achieved as discussed in below thread, but care should be taken on how long to block and other dead lock scenarios.
ThreadPoolExecutor Block When Queue Is Full?