Home > Software design >  How to delay a scheduled task with Spring?
How to delay a scheduled task with Spring?

Time:08-04

I'd like to create a method that delays the execution on method invocation by 60s.

Problem: if the method is called within that 60s, I want it to be delayed again by 60s from last point of invocation. If then not called within 60s, the execution may continue.

I started as follows, but of course this is only a one-time delay:

public void sendDelayed(String info) {
   //TODO create a task is delayed by  60s for each method invocation 
   ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
   executorService.schedule(Classname::someTask, 60, TimeUnit.SECONDS);
}

How could I further delay the execution on each invocation?

CodePudding user response:

executorService.schedule returns a ScheduledFuture which provides a cancel method to cancel its execution. cancel takes a single boolean parameter mayInterruptIfRunning which, when set to false, will only cancel the execution if the task has not started yet. See also the docs.

Using this you could do something like this:

private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

private ScheduledFuture<?> future;

public void sendDelayed(String info) {
    // When there is a task that has not been started yet, stop it:
    if (future != null) {
        boolean cancelled = future.cancel(false);
        if (cancelled) {
            logger.debug("Task has been cancelled before execution");
        } else {
            logger.debug("Task is already running or has been completed");
        }
    }

    // Old task has been cancelled or already started - schedule a new task
    future = executorService.schedule(Classname::someTask, 60, TimeUnit.SECONDS);
}

You may have to take care of avoiding race conditions regarding concurrent access to the future field though.

  • Related