I have a requirement to create a task scheduler with 10 threads that we need to fire at the same time and each thread will come back with a status of complete or failed. Based on the result of the thread, we will make a db call and fetch the data from db. The application is already configured with Spring Framework. I understand that spring provides task scheduler, but not sure how to use it, spring newbie needs help. How about java's ScheduledExecutorService, can we use that? What advantage we will get one over the other? Is there a better alternative to Spring task scheduler and Java's ScheduledExecutorService?
ScheduledExecutorService is an ExecutorService which can schedule tasks to run after a delay, or to execute repeatedly with a fixed interval of time in between each execution. Tasks are executed asynchronously by a worker thread, and not by the thread handing the task to the ScheduledExecutorService .
The ScheduledExecutorService interface in Java is a sub-interface of ExecutorService interface defined in java. util. concurrent package. This interface is used to run the given tasks periodically or once after a given delay.
We can easily schedule tasks in spring boot by using @Scheduled annotation. And then we need to enable scheduling by adding @EnableScheduling annotation to a spring configuration class. Spring uses ThreadPoolTaskScheduler for scheduled tasks, which internally delegates to a ScheduledExecutorService.
Note that scheduled tasks don't run in parallel by default. So even if we used fixedRate, the next task won't be invoked until the previous one is done. Now this asynchronous task will be invoked each second, even if the previous task isn't done.
Spring TaskExecutor
is actually identical to java Executor
interface. After Spring 2.0 TaskExecutor
has been introduced to add abstraction to the Java's Executor
, so that it will hide implementation details between Java SE different versions and EE environments.
As you have already Spring environment, I'd strongly recommend to use spring schedulers. Later on if there will be need you can give other Spring components an abstraction for thread pooling, etc.
Also there are some pre-built implementations of TaskExecutor, which is ideal, as you don't have to care about the details and implementation by your own.
The simplest way is to use the provided task tags in the spring config. Notice the 'task' namespace below
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:ctx="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
">
once you've done that you can use
<task:scheduler id="taskScheduler" pool-size="4"/>
<task:scheduled-tasks scheduler="taskScheduler">
<task:scheduled ref="someBean" method="someMethod" fixed-rate="21600000" initial-delay="60000"/>
</task:scheduled-tasks>
etc. your actual scheduled task is a bean with a method on it that gets called. You can schedule it on a fixed delay or on a cron etc.
you can also declare executors in the config like this :
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<description>A task pool for general use</description>
<property name="corePoolSize" value="150" />
<property name="maxPoolSize" value="200" />
<property name="queueCapacity" value="10" />
<property name="keepAliveSeconds" value="0"/>
<property name="waitForTasksToCompleteOnShutdown" value="false"/>
</bean>
You can use an executor to execute a pool of concurrent tasks (inject that bean into your bean and look at what it provides).
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