在本教程中,我们将讨论 Spring 任务调度机制, TaskScheduler, 以及它的预构建实现。然后我们将探索要使用的不同触发器。
Spring 3.0 引入了TaskScheduler*,其中包含多个可以配置在未来某个时间点运行的方法。 *TaskScheduler 还返回 ScheduledFuture 接口的表示对象,我们可以使用它来取消计划任务并检查它们是否已完成。
我们需要做的就是选择一个可运行的任务进行调度,然后选择一个合适的调度策略。
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调度机制。
我们可以使用两种简单的机制来安排固定延迟:
让我们配置一个任务在 1000 毫秒的固定延迟后运行:
taskScheduler.scheduleWithFixedDelay(
new RunnableTask("Fixed 1 second Delay"), 1000);
RunnableTask 将始终在一次执行完成和下一次执行开始之间运行 1000 毫秒。
让我们将任务配置为在给定开始时间的固定延迟后运行:
taskScheduler.scheduleWithFixedDelay(
new RunnableTask("Current Date Fixed 1 second Delay"),
new Date(),
1000);
RunnableTask 将在指定的执行时间被调用,其中包括 @PostConstruct 方法开始的时间,随后延迟 1000 毫秒。
有两种简单的机制可以以固定速率调度可运行任务。
让我们安排一个任务以固定的毫秒速率运行:
taskScheduler.scheduleAtFixedRate(
new RunnableTask("Fixed Rate of 2 seconds") , 2000);
下一个 RunnableTask 将始终在 2000 毫秒后运行,而不管上次执行的状态如何,它可能仍在运行。
taskScheduler.scheduleAtFixedRate(
new RunnableTask("Fixed Rate of 2 seconds") , 2000);
RunnableTask 将在当前时间后 3000 毫秒运行。
我们使用CronTrigger 来根据 cron 表达式调度任务:
taskScheduler.scheduleAtFixedRate(new RunnableTask(
"Fixed Rate of 2 seconds"), new Date(), 3000);
我们可以使用提供的触发器按照某个指定的节奏或时间表运行任务:
taskScheduler.schedule(new RunnableTask("Cron Trigger"), cronTrigger);
在这种情况下,RunnableTask 将在每分钟的第 10 秒执行。
让我们使用 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 方法设置第一个可运行任务运行的初始延迟。
在这篇简短的文章中,我们学习了如何使用 Spring 对任务的支持来安排可运行的任务。
我们演示了以固定延迟、固定速率并根据指定触发器运行任务。
本文亦通过 NoOne 的个人博客 发表。