How to stop a scheduled task that was started using @Scheduled annotation?

后端 未结 8 1535
挽巷
挽巷 2020-11-27 03:52

I have created a simple scheduled task using Spring Framework\'s @Scheduled annotation.

 @Scheduled(fixedRate = 2000)
 public void doSomething() {}


        
相关标签:
8条回答
  • 2020-11-27 04:52

    Here is an example where we can stop , start , and list also all the scheduled running tasks:

    @RestController
    @RequestMapping("/test")
    public class TestController {
    
    private static final String SCHEDULED_TASKS = "scheduledTasks";
    
    @Autowired
    private ScheduledAnnotationBeanPostProcessor postProcessor;
    
    @Autowired
    private ScheduledTasks scheduledTasks;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    @GetMapping(value = "/stopScheduler")
    public String stopSchedule(){
        postProcessor.postProcessBeforeDestruction(scheduledTasks, SCHEDULED_TASKS);
        return "OK";
    }
    
    @GetMapping(value = "/startScheduler")
    public String startSchedule(){
        postProcessor.postProcessAfterInitialization(scheduledTasks, SCHEDULED_TASKS);
        return "OK";
    }
    
    @GetMapping(value = "/listScheduler")
    public String listSchedules() throws JsonProcessingException{
        Set<ScheduledTask> setTasks = postProcessor.getScheduledTasks();
        if(!setTasks.isEmpty()){
            return objectMapper.writeValueAsString(setTasks);
        }else{
            return "No running tasks !";
        }
     }
    }
    
    0 讨论(0)
  • 2020-11-27 04:55

    Scheduled

    When spring process Scheduled, it will iterate each method annotated this annotation and organize tasks by beans as the following source shows:

    private final Map<Object, Set<ScheduledTask>> scheduledTasks =
            new IdentityHashMap<Object, Set<ScheduledTask>>(16);
    

    Cancel

    If you just want to cancel the a repeated scheduled task, you can just do like following (here is a runnable demo in my repo):

    @Autowired
    private ScheduledAnnotationBeanPostProcessor postProcessor;
    @Autowired
    private TestSchedule testSchedule;
    
    public void later() {
        postProcessor.postProcessBeforeDestruction(test, "testSchedule");
    }
    

    Notice

    It will find this beans's ScheduledTask and cancel it one by one. What should be noticed is it will also stopping the current running method (as postProcessBeforeDestruction source shows).

        synchronized (this.scheduledTasks) {
            tasks = this.scheduledTasks.remove(bean); // remove from future running
        }
        if (tasks != null) {
            for (ScheduledTask task : tasks) {
                task.cancel(); // cancel current running method
            }
        }
    
    0 讨论(0)
提交回复
热议问题