Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Task Scheduler vs. Java's ScheduledExecutorService

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?

like image 256
Rasoul Avatar asked Feb 11 '15 14:02

Rasoul


People also ask

Is ScheduledExecutorService asynchronous?

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 .

What is a 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.

How do I run multiple scheduler in spring boot?

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.

Is @scheduled asynchronous?

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.


2 Answers

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.

like image 51
vtor Avatar answered Sep 19 '22 14:09

vtor


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).

like image 32
Richard Avatar answered Sep 18 '22 14:09

Richard