弹簧调度任务 - 仅运行一次

2022-09-01 02:46:05

是否可以在确切的指定时间只安排一次Spring服务方法?例如,当前时间是下午2点,但当我点击操作按钮时,我希望我的服务方法在晚上8点开始。我熟悉@Scheduled注释,我不确定如何编写cron表达式不定期运行。这个每天晚上8点开火。
有什么建议吗?@Scheduled(cron = "0 0 20 * * ?")


答案 1

死人的解决方案:

@Scheduled(initialDelay = 1000 * 30, fixedDelay=Long.MAX_VALUE)

在它再次开火之前,你会死去。


答案 2

您可以使用Spring的TaskScheduler的实现之一。我在下面提供了一个不需要太多配置的示例(包装单线程计划执行器的 ConcurrentTaskScheduler)。

最简单的方法是一个命名的计划,它只采用Runnable和Date。这将导致任务在指定时间后运行一次。所有其他方法都能够计划任务重复运行。

阅读更多有关任务执行和计划的信息

简单工作示例:

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

注意

要启用对@Scheduled和@Async批注的支持,请将@EnableScheduling和@EnableAsync添加到@Configuration类之一


更新 - 取消计划任务

TaskScheduler 的 schedule 方法返回一个 ScheduledFuture,这是一个可以取消的延迟结果承载操作

因此,为了取消它,您需要保留计划任务的句柄(即保留SchurdFuture返回对象)。

对上述取消任务的代码的更改:

  1. 在 executeTaskT 方法外部声明 ScheduledFuture。
    private ScheduledFuture scheduledFuture;
  1. 修改对计划的调用,以保持返回对象如下:
    scheduledFuture = scheduler.schedule(exampleRunnable,
                    new Date(1432152000000L));
  1. 对代码中某个位置的计划未来对象调用取消
    boolean mayInterruptIfRunning = true;
    scheduledFuture.cancel(mayInterruptIfRunning);

推荐