1. 概述

在本教程中,咱们将探讨 Spring 任务调度机制, TaskScheduler, 以及它的预构建实现。而后咱们将摸索要应用的不同触发器。

Spring 3.0 引入了TaskScheduler,其中蕴含多个能够配置在将来某个工夫点运行的办法。 TaskScheduler 还返回 ScheduledFuture 接口的示意对象,咱们能够应用它来勾销打算工作并查看它们是否已实现。

咱们须要做的就是抉择一个可运行的工作进行调度,而后抉择一个适合的调度策略。

  1. ThreadPoolTaskScheduler

ThreadPoolTaskScheduler 对于外部线程治理很有用,因为它将工作委托给 ScheduledExecutorService 并实现 TaskExecutor 接口。它的单个实例可能解决异步潜在执行,以及 @Scheduled 正文。

让咱们在 ThreadPoolTaskSchedulerConfig 中定义 ThreadPoolTaskScheduler bean:

@Configuration@ComponentScan(  basePackages="com.baeldung.taskscheduler",  basePackageClasses={ThreadPoolTaskSchedulerExamples.class})public class ThreadPoolTaskSchedulerConfig {    @Bean    public ThreadPoolTaskScheduler threadPoolTaskScheduler(){        ThreadPoolTaskScheduler threadPoolTaskScheduler          = new ThreadPoolTaskScheduler();        threadPoolTaskScheduler.setPoolSize(5);        threadPoolTaskScheduler.setThreadNamePrefix(          "ThreadPoolTaskScheduler");        return threadPoolTaskScheduler;    }}

配置的 bean threadPoolTaskScheduler 能够依据配置的池大小 5 异步执行工作。

请留神,所有与 ThreadPoolTaskScheduler 相干的线程名称都将以 ThreadPoolTaskScheduler 为前缀。

让咱们实现一个简略的工作,而后咱们能够安顿:

class RunnableTask implements Runnable{    private String message;        public RunnableTask(String message){        this.message = message;    }        @Override    public void run() {        System.out.println(new Date()+" Runnable Task with "+message          +" on thread "+Thread.currentThread().getName());    }}

咱们当初能够调度调度器来执行这个工作:

taskScheduler.schedule(  new Runnabletask("Specific time, 3 Seconds from now"),  new Date(System.currentTimeMillis + 3000));

taskScheduler 将把这个可运行的工作安顿在一个已知的日期,即以后工夫之后的 3 秒。

当初让咱们更深刻地理解ThreadPoolTaskScheduler调度机制。

  1. 以固定提早安顿可运行工作

咱们能够应用两种简略的机制来安顿固定提早:

3.1 在最初一次打算执行的固定提早后执行

让咱们配置一个工作在 1000 毫秒的固定提早后运行:

taskScheduler.scheduleWithFixedDelay(  new RunnableTask("Fixed 1 second Delay"), 1000);

RunnableTask 将始终在一次执行实现和下一次执行开始之间运行 1000 毫秒。

3.2 在特定日期的固定提早后执行

让咱们将工作配置为在给定开始工夫的固定提早后运行:

taskScheduler.scheduleWithFixedDelay(  new RunnableTask("Current Date Fixed 1 second Delay"),  new Date(),  1000);

RunnableTask 将在指定的执行工夫被调用,其中包含 @PostConstruct 办法开始的工夫,随后提早 1000 毫秒。

  1. 以固定速率调度

有两种简略的机制能够以固定速率调度可运行工作。

4.1 以固定速率调度 RunnableTask

让咱们安顿一个工作以固定的毫秒速率运行:

taskScheduler.scheduleAtFixedRate(  new RunnableTask("Fixed Rate of 2 seconds") , 2000);

下一个 RunnableTask 将始终在 2000 毫秒后运行,而不论上次执行的状态如何,它可能仍在运行。

4.2 从给定日期以固定速率调度 RunnableTask

taskScheduler.scheduleAtFixedRate(  new RunnableTask("Fixed Rate of 2 seconds") , 2000);

RunnableTask 将在以后工夫后 3000 毫秒运行。

  1. 应用 CronTrigger 进行调度

咱们应用CronTrigger 来依据 cron 表达式调度工作:

taskScheduler.scheduleAtFixedRate(new RunnableTask(  "Fixed Rate of 2 seconds"), new Date(), 3000);

咱们能够应用提供的触发器依照某个指定的节奏或时间表运行工作:

taskScheduler.schedule(new RunnableTask("Cron Trigger"), cronTrigger);

在这种状况下,RunnableTask 将在每分钟的第 10 秒执行。

  1. 应用 PeriodicTrigger 进行调度

让咱们应用 PeriodicTrigger 以 2000 毫秒的固定提早调度工作:

PeriodicTrigger periodicTrigger   = new PeriodicTrigger(2000, TimeUnit.MICROSECONDS);

配置的 PeriodicTrigger bean 用于在 2000 毫秒的固定提早后运行工作。

当初让咱们用 PeriodicTrigger 安顿 RunnableTask

taskScheduler.schedule(  new RunnableTask("Periodic Trigger"), periodicTrigger);

咱们还能够配置 PeriodicTrigger 以固定速率初始化,而不是固定提早。此外,咱们能够为第一个打算工作设置一个给定毫秒的初始提早。

咱们须要做的就是在 periodicTrigger bean 的 return 语句之前增加两行代码

periodicTrigger.setFixedRate(true);periodicTrigger.setInitialDelay(1000);

咱们应用 setFixedRate 办法以固定速率而不是固定提早来调度工作。而后咱们应用 setInitialDelay 办法设置第一个可运行工作运行的初始提早。

  1. 论断

在这篇简短的文章中,咱们学习了如何应用 Spring 对工作的反对来安顿可运行的工作。

咱们演示了以固定提早、固定速率并依据指定触发器运行工作。

本文代码能够在 GitHub 找到。

本文亦通过 NoOne 的集体博客 发表。