I have a task scheduled as such:
<task:scheduler id="notification.scheduler" pool-size="15" />
<task:scheduled-tasks scheduler="notification.scheduler">
<task:scheduled ref="notificationProcessor" method="sendNextQueueEvent" fixed-rate="500" />
<task:scheduled ref="notificationProcessor" method="deleteNextCompletedEvent" fixed-rate="60000" />
</task:scheduled-tasks>
I think I have a misunderstanding of how the scheduled tasks work with the pool size. Despite the pool-size being 15, it seems only one thread is being used. For example, if I have fifteen events in the queue, I would think there would be fifteen threads checking every minute to remove an event from the queue. Obviously, this is wrong.
How can I make it so that there's fifteen threads calling this method for the time interval using Spring's scheduler abstraction?
Edit: What I want to accomplish is this: Every half second, I want to check to see if there are queued events to send. When this is done, I want to send a maximum of 15 (if 15 exist). How would I accomplish this using the spring abstractions for the java thread stuff?
spring.task.scheduling.pool.size=20. The same task will be executed in serialized when the trigger period is shorter than the execution duration. And Spring Boot will execute different tasks in parallel with a maximum of 20 threads.
We can turn any method in a Spring bean for scheduling by adding the @Scheduled annotation to it. The @Scheduled is a method-level annotation applied at runtime to mark the method to be scheduled. It takes one attribute from cron , fixedDelay , or fixedRate for specifying the schedule of execution in different formats.
The TaskExecutor was originally created to give other Spring components an abstraction for thread pooling where needed. Components such as the ApplicationEventMulticaster , JMS's AbstractMessageListenerContainer , and Quartz integration all use the TaskExecutor abstraction to pool threads.
First of all <task:scheduler/>
is a wrapper around ScheduledThreadPoolExecutor
extending ThreadPoolExecutor
. JavaDoc for the latter says:
even core threads are initially created and started only when new tasks arrive
Secondly you must understand that scheduled tasks (this is a Java feature, not Spring's) do not run concurrently, even if they take longer time than repeat interval. They simply wait. So you don't have 15 events waiting in the queue, you have 15 executions that are late and wait for that single thread. No need to create another one because next execution has to wait for the previous one to finish. Again, this is how Java scheduling framework works.
Of course if you have several different tasks scheduled, more threads will be created.
Spring's task:scheduler
is by default a bean properties wrapper for java.util.concurrent.ThreadPoolExecutor
:
corePoolSize - the number of threads to keep in the pool, even if they are idle.
This does not guarantee that the pools-size
property is equivalent to having that number of active threads. On the other hand, you should note that at any given point in time there can be only a maximum number of threads equal to processing cores on the machine that you're using; i.e. all other threads will be waiting to switch to RUNNING
mode and continue execution.
Also, in Spring's documentation, it mentions that if this is not what you need, you can also take advantage of ConcurrentTaskExecutor
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With