A Guide to the Spring Task Scheduler – Spring Task Scheduler指南

最后修改: 2017年 1月 13日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll discuss the Spring task scheduling mechanism, TaskScheduler, and it’s pre-built implementations. Then we’ll explore the different triggers to use. To read more about scheduling in Spring, can check out these @Async and @Scheduled articles.

在本教程中,我们将讨论Spring任务调度机制,TaskScheduler,以及它的预构建的实现。然后我们将探索不同的触发器的使用。要阅读更多关于Spring调度的内容,可以查看这些@Async@Scheduled文章。

Spring 3.0 introduced TaskScheduler with a variety of methods designed to run at some point in the future. TaskScheduler also returns a representation object of the ScheduledFuture interface, which we can use to cancel scheduled tasks and check to see if they’re done or not.

Spring 3.0 引入了TaskScheduler,其中有多种方法被设计为在未来的某个时间点运行。TaskScheduler还返回了ScheduledFuture接口的表示对象,我们可以用它来取消计划任务,并检查它们是否已经完成。

All we need to do is select a runnable task for scheduling, then select a proper scheduling policy.

我们需要做的就是选择一个可运行的任务进行调度,然后选择一个合适的调度策略。

2. ThreadPoolTaskScheduler

2.ThreadPoolTaskScheduler

ThreadPoolTaskScheduler is useful for internal thread management, as it delegates tasks to the ScheduledExecutorService, and implements the TaskExecutor interface. A single instance of it is able to handle asynchronous potential executions, as well as the @Scheduled annotation.

ThreadPoolTaskScheduler对于内部线程管理非常有用,因为它将任务委托给ScheduledExecutorService并实现了TaskExecutor接口。它的一个实例能够处理异步的潜在执行,以及@Scheduled注解。

Let’s define the ThreadPoolTaskScheduler bean at ThreadPoolTaskSchedulerConfig:

让我们在ThreadPoolTaskScheduler中定义ThreadPoolTaskSchedulerConfig的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;
    }
}

The configured bean threadPoolTaskScheduler can execute tasks asynchronously based on the configured pool size of 5.

配置的Bean threadPoolTaskScheduler 可以根据配置的5个池的大小异步地执行任务。

Note that all ThreadPoolTaskScheduler related thread names will be prefixed with ThreadPoolTaskScheduler.

请注意,所有ThreadPoolTaskScheduler相关的线程名称将以ThreadPoolTaskScheduler为前缀。

Let’s implement a simple task we can then schedule:

让我们实现一个简单的任务,然后我们可以安排。

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());
    }
}

We can now schedule the scheduler to execute this task:

我们现在可以安排调度程序来执行这个任务。

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

The taskScheduler will schedule this runnable task at a known date, exactly 3 seconds after the current time.

taskScheduler将在一个已知的日期安排这个可运行的任务,正好在当前时间后3秒。

Now let’s go a bit more in-depth with the ThreadPoolTaskScheduler scheduling mechanisms.

现在让我们更深入地了解一下ThreadPoolTaskScheduler调度机制。

3. Schedule Runnable Task With Fixed Delay

3.安排具有固定延迟的可运行任务

We can schedule a fixed delay with two simple mechanisms:

我们可以通过两个简单的机制来安排一个固定的延迟。

3.1. Scheduling After a Fixed Delay of the Last Scheduled Execution

3.1.在最后一次预定执行的固定延迟后进行调度

Let’s configure a task to run after a fixed delay of 1000 milliseconds:

让我们配置一个任务,在1000毫秒的固定延迟后运行。

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

The RunnableTask will always run 1000 milliseconds later between the completion of one execution and the start of the next.

RunnableTask在完成一次执行和开始下一次执行之间总是晚1000毫秒运行。

3.2. Scheduling After a Fixed Delay of a Specific Date

3.2.特定日期的固定延迟后的调度

Let’s configure a task to run after a fixed delay of a given start time:

让我们配置一个任务,在给定的启动时间的固定延迟后运行。

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

The RunnableTask will be invoked at the specified execution time, which encompasses the time in which the @PostConstruct method starts, and subsequently with 1000 milliseconds delay.

RunnableTask将在指定的执行时间被调用,其中包括@PostConstruct方法开始的时间,以及随后的1000毫秒延迟。

4. Scheduling at a Fixed Rate

4.按固定费率排班

There are two simple mechanisms for scheduling runnable tasks at a fixed rate.

有两种简单的机制用于以固定速率调度可运行的任务。

4.1. Scheduling the RunnableTask at a Fixed Rate

4.1.以固定速率调度RunnableTask

Let’s schedule a task to run at a fixed rate of milliseconds:

让我们安排一个任务以固定的毫秒率运行。

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

The next RunnableTask will always run after 2000 milliseconds, regardless of the status of the last execution, which may still be running.

下一个RunnableTask将总是在2000毫秒后运行,不管上一次执行的状态如何,它可能仍在运行。

4.2. Scheduling the RunnableTask at a Fixed Rate From a Given Date

4.2.从一个给定的日期开始,以固定的速率调度RunnableTask

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

The RunnableTask will run 3000 milliseconds after the current time.

RunnableTask将在当前时间后的3000毫秒内运行。

5. Scheduling with CronTrigger

5.用CronTrigger进行调度

We use CronTrigger to schedule a task based on a cron expression:

我们使用 CronTrigger 来安排一个基于cron表达式的任务。

CronTrigger cronTrigger 
  = new CronTrigger("10 * * * * ?");

We can use the provided trigger to run a task according to a certain specified cadence or schedule:

我们可以使用所提供的触发器,按照某个指定的节奏或时间表来运行一个任务。

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

In this case, the RunnableTask will be executed at the 10th second of every minute.

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

6. Scheduling With PeriodicTrigger

6.使用周期性触发器进行调度

Let’s use PeriodicTrigger for scheduling a task with a fixed delay of 2000 milliseconds:

让我们使用PeriodicTrigger来调度一个具有固定延迟2000毫秒的任务。

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

The configured PeriodicTrigger bean is used to run a task after a fixed delay of 2000 milliseconds.

配置的PeriodicTriggerBean被用来在2000毫秒的固定延迟后运行一个任务。

Now let’s schedule the RunnableTask with the PeriodicTrigger:

现在让我们用PeriodicTrigger来安排RunnableTask

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

We can also configure PeriodicTrigger to be initialized at a fixed rate, rather than a fixed delay. Furthermore, we can set an initial delay for the first scheduled task by a given milliseconds.

我们还可以配置PeriodicTrigger,使其以固定的速率而不是固定的延迟进行初始化。此外,我们还可以为第一个计划任务设置一个给定的毫秒的初始延迟。

All we need to do is add two lines of code before the return statement at the periodicTrigger bean:

我们需要做的就是在periodicTrigger Bean的返回语句前添加两行代码

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

We used the setFixedRate method to schedule the task at a fixed rate, rather than with a fixed delay. Then we used the setInitialDelay method to set an initial delay for the first runnable task to run.

我们使用setFixedRate方法来安排任务的固定速率,而不是固定延迟。然后我们使用setInitialDelay方法为第一个可运行任务的运行设置一个初始延迟。

7. Conclusion

7.结语

In this brief article, we learned how to schedule a runnable task using the Spring support for tasks.

在这篇简短的文章中,我们学习了如何使用Spring对任务的支持来安排一个可运行的任务。

We demonstrated running the task with a fixed delay, at a fixed rate, and according to a specified trigger.

我们演示了以固定的延迟、固定的速率和根据指定的触发器来运行任务。

As always, the code is available as a Maven project over in GitHub.

一如既往,该代码可作为Maven项目在GitHub上获得。