I have the following task scheduler setup:
<bean id="Task" class="foo.bar.Task" />
<bean id="TaskScheduler"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
<property name="waitForTasksToCompleteOnShutdown" value="true" />
<property name="poolSize" value="1000" />
</bean>
<task:scheduled-tasks scheduler="TaskScheduler">
<task:scheduled ref="Task" method="run" cron="*/5 * * * * *" />
</task:scheduled-tasks>
The Task just prints a line and sleeps for 10 seconds. With this setup, my expectation was that the task would run every 5 seconds, regardless of whether the previous task had finished it's execution (ie stopped sleeping). But that's not the case, the task runs once ever 15 seconds (the sleep time and then the next time the cron is hit).
How can I configure this so that the task runs every 5 seconds regardless of whether the previous execution finished?
by default, spring uses a single-threaded Executor. so no two @Scheduled tasks will ever overlap. even two @Scheduled methods in completely unrelated classes will not overlap simply because there is only a single thread to execute all @Scheduled tasks.
Schedule a Task at Fixed Delay In this case, the duration between the end of the last execution and the start of the next execution is fixed. The task always waits until the previous one is finished. This option should be used when it's mandatory that the previous execution is completed before running again.
Java Cron ExpressionThe @EnableScheduling annotation is used to enable the scheduler for your application. This annotation should be added into the main Spring Boot application class file. The @Scheduled annotation is used to trigger the scheduler for a specific time period.
ThreadPoolTaskScheduler ThreadPoolTaskScheduler is well suited for internal thread management, as it delegates tasks to the ScheduledExecutorService and implements the TaskExecutor interface – so that single instance of it is able to handle asynchronous potential executions as well as the @Scheduled annotation.
In you run method put @Async anotation and see
@Async
public void run{
}
or you can
Try out this
<bean id="schedulerTask"
class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
<property name="mytaskClass" ref="mytaskClass" />
<property name="targetMethod" value="fooMethod" />
</bean>
<bean id="mytaskClass" class="foo.bar.Task" />
<bean id="timerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask" ref="schedulerTask" />
<property name="delay" value="10" />
<property name="period" value="5000" />
</bean>
<bean class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref local="timerTask" />
</list>
</property>
</bean>
Then Your class
package foo.bar;
public class Task{
public void fooMethod(){
// do task
}
}
Added as per the request
<!-- Thread pool related configurations -->
<bean name="workerThread" class="foo.WorkerThread"/>
<bean name="managerThread" class="foo.ManagerThread" >
<constructor-arg type="org.springframework.core.task.TaskExecutor" ref="taskExecutor" />
<constructor-arg type="foo.process.WorkerThread" ref="workerThread"/>
</bean>
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="30" />
<property name="queueCapacity" value="100" />
</bean>
<!-- End Thread pool related configurations -->
ManagerThread.java
public class ManagerThread {
private TaskExecutor taskExecutor=null;
private WorkerThread workerThread=null;
/**
* @param taskExecutor
* @param workerThread
*/
public ManagerThread(final TaskExecutor taskExecutor,final WorkerThread workerThread) {
this.taskExecutor = taskExecutor;
this.workerThread = workerThread;
}
/**
* Create a new thread and execte the requests
* @param parameter
*/
public synchronized void fire(final Object parameter) {
taskExecutor.execute( new Runnable() {
public void run() {
workerThread.execute( parameter );
}
});
}
WorkerThread.java
@Component
public class WorkerThread {
public void execute(final Object request) {
// do the job
}
}
You could customize this as per your requirement
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