Spring offers @Scheduled
annotation to configure and schedule tasks. Methods annotated with @Scheduled
are automatically scheduled. If you are not familiar with this read the following article by Eugen.
https://www.baeldung.com/spring-scheduled-tasks
We will be leveraging Spring's ThreadPoolTaskScheduler
to implement our custom task scheduler which we can programmatically trigger.
The ThreadPoolTaskScheduler
helps manage threads internally by assigning tasks to the ScheduledExecutorService
and implements TaskExecutor
interface. With just one instance, it can handle tasks that might run asynchronously, including those marked with the @Scheduled
annotation.
public class CustomTaskScheduler extends ThreadPoolTaskScheduler {
private final Map<String, ScheduledFuture<?>> scheduledTasks = new IdentityHashMap<>();
public void scheduleAtFixedRate(Runnable task, Duration period, String id) {
ScheduledFuture<?> future = super.scheduleAtFixedRate(task, period);
scheduledTasks.put(id, future);
}
}
Just like @Scheduled(fixedRate = 1000)
, super.scheduleAtFixedRate(task, period)
we have provided a fixed Duration
. We will later implement our Runnable
task.
super.scheduleAtFixedRate(task, period)
returns a ScheduledFuture
which is basically a delayed result that can be cancelled at any time. So to get hold of it later we are keeping ScheduledFuture
in scheduledTasks
.
Let's see how we can cancel the ScheduledFuture
.
public void cancelScheduledTask(String id) {
ScheduledFuture<?> future = scheduledTasks.get(id);
if (null != future) {
future.cancel(true);
}
}
If the task has not started when cancel is called, the task will never run. If the task has already started, then the future.cancel(true)
accepts a boolean parameter, mayInterruptIfRunning
, which determines whether the thread executing this task is interrupted in an attempt to stop the task. Passing true means interrupted the task if needed.
Now, let's implement task which we need to schedule.
public class RunnableTask implements Runnable {
private String id;
public RunnableTask() {
}
public RunnableTask(String id) {
this.id = id;
}
@Override
public void run() {
// perform task here
}
}
An example to schedule task:
String id = UUID.randomUUID().toString();
RunnableTask task = new RunnableTask(id);
customTaskScheduler.scheduleAtFixedRate(task,Duration.ofMinutes(1, id);
Top comments (0)