Spring Scheduling Task - Run Only Once

Spring scheduling task - run only once

You can use one of Spring's TaskScheduler's implementations. I provided an example below with one which does not require too much configuration (ConcurrentTaskScheduler that wraps a single-threaded scheduled executor).

The simplest method is the one named schedule that takes a Runnable
and Date only. That will cause the task to run once after the
specified time. All of the other methods are capable of scheduling
tasks to run repeatedly.

Read more on task execution & scheduling

Simple working example:

private TaskScheduler scheduler;

Runnable exampleRunnable = new Runnable(){
@Override
public void run() {
System.out.println("Works");
}
};

@Async
public void executeTaskT() {
ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor();
scheduler = new ConcurrentTaskScheduler(localExecutor);

scheduler.schedule(exampleRunnable,
new Date(1432152000000L));//today at 8 pm UTC - replace it with any timestamp in miliseconds to text
}

...

executeTaskT() //call it somewhere after the spring application has been configured

Note:

To enable support for @Scheduled and @Async annotations add
@EnableScheduling and @EnableAsync to one of your @Configuration
classes


Update - cancelling the scheduled task

TaskScheduler's schedule method returns a ScheduledFuture which is a delayed result-bearing action that can be cancelled.

So in order to cancel it, you need to keep a handle to the scheduled task (i.e. keep the ScheduledFuture return object).

Changes to the code above for cancelling the task :

  1. Declare the ScheduledFuture outside your executeTaskT method.
    private ScheduledFuture scheduledFuture;

  1. Modify your call to schedule to keep the return object as such:
    scheduledFuture = scheduler.schedule(exampleRunnable,
new Date(1432152000000L));

  1. Call cancel on the scheduledFuture object somewhere in your code
    boolean mayInterruptIfRunning = true;
scheduledFuture.cancel(mayInterruptIfRunning);

How to run @Scheduled job at exact time for once in Spring?

This is a workaround to your solution. Just use the scheduled annotation as it is but Use Date with it. That is

    String targetDate="2020-02-06 13:50:00";
Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(targetDate);
if(new Date().getTime()==date.getTime())
{
then put your logic here.
}

edit -> Just checking the year would be enough right. So you can do this.

@Scheduled(cron = "0 50 13 6 2 ?")
public void doTheJobForOnceInSpecificTime() {
if (Year.now().getValue() == 2020) {
//your logic
}
}

Spring, Run task once when application started

If it has to be run once immediately after application is initialized, I would simply start it from the init method of a singleton bean. Spring ensures that at be time it will be run all dependant beans will have been initialized.

For example, assuming a Java annotation Spring configuration you could use something like:

@Bean(init_method="init")
class TaskLauncher {

@Autowired DependantBeanClass dependant Bean;
...

public void init() {
// execute or start the task, eventually using the autowired dependant beans
...
}
}

When the context is refreshed, Spring autowire everything, initializes the dependant beans and then will call once the init method of the TaskLauncher bean.

No need for @Scheduler nor Quartz if you only need to start something at Spring initialization time



Related Topics



Leave a reply



Submit