Java – Spring ScheduledTask – start/stop support

javascheduled-tasksspring

Is there a way to start or stop a task scheduled using Spring Scheduled Tasks initialized using context file or @Scheduled annotation?

I would like to start the task when required and stop it when the task is no longer needed to be run.

If this is not possible, any alternative to injecting spring variables to a thread?

Best Answer

Here is an example of starting/stopping a scheduled method in Spring Boot. You can use such APIs:
http:localhost:8080/start - for starting scheduled method with fixed rate 5000 ms
http:localhost:8080/stop - for stopping scheduled method

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.time.Instant;
import java.util.concurrent.ScheduledFuture;

@Configuration
@ComponentScan
@EnableAutoConfiguration    
public class TaskSchedulingApplication {

    public static void main(String[] args) {
        SpringApplication.run(TaskSchedulingApplication.class, args);
    }

    @Bean
    TaskScheduler threadPoolTaskScheduler() {
        return new ThreadPoolTaskScheduler();
    }
}

@Controller
class ScheduleController {

    public static final long FIXED_RATE = 5000;

    @Autowired
    TaskScheduler taskScheduler;

    ScheduledFuture<?> scheduledFuture;

    @RequestMapping("start")
    ResponseEntity<Void> start() {
        scheduledFuture = taskScheduler.scheduleAtFixedRate(printHour(), FIXED_RATE);

        return new ResponseEntity<Void>(HttpStatus.OK);
    }

    @RequestMapping("stop")
    ResponseEntity<Void> stop() {
        scheduledFuture.cancel(false);
        return new ResponseEntity<Void>(HttpStatus.OK);
    }

    private Runnable printHour() {
        return () -> System.out.println("Hello " + Instant.now().toEpochMilli());
    }

}