1. 概述
在这个教程中,我们将探讨Spring的任务调度机制——TaskScheduler
及其预构建实现。然后,我们将深入研究不同的触发器用法。想要了解更多关于Spring中的调度,可以查阅这些文章:异步执行和定时任务。
Spring 3.0引入了TaskScheduler
,它提供了一系列方法,用于在未来某个时间点执行任务。TaskScheduler
还返回一个ScheduledFuture
接口的表示对象,我们可以使用它来取消已安排的任务或检查它们是否已完成。
我们只需选择一个可运行的任务进行调度,并选择合适的调度策略即可。
2. ThreadPoolTaskScheduler
ThreadPoolTaskScheduler
对于内部线程管理很有用,因为它将任务委托给ScheduledExecutorService
,并实现了TaskExecutor
接口。它能处理单个实例的异步潜在执行,以及@Async
和@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
在已知的时间后执行这个任务:
taskScheduler.schedule(
new Runnabletask("Specific time, 3 Seconds from now"),
new Date(System.currentTimeMillis + 3000)
);
taskScheduler
将在当前时间之后的3秒准确地安排这个可运行任务。
现在让我们更深入地了解ThreadPoolTaskScheduler
的调度机制。
3. 根据固定延迟安排可运行任务
我们可以使用两种简单方式安排一个固定的延迟:
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毫秒延迟后。
4. 定时任务的固定速率安排
有两种简单方式安排以固定速率运行的可运行任务。
4.1. 按固定速率安排RunnableTask
让我们安排一个任务,每2000毫秒运行一次:
taskScheduler.scheduleAtFixedRate(
new RunnableTask("Fixed Rate of 2 seconds") , 2000);
无论上次执行状态如何(可能仍在运行),下一个RunnableTask
总是在2000毫秒后运行。
4.2. 从给定日期开始按固定速率安排RunnableTask
taskScheduler.scheduleAtFixedRate(new RunnableTask(
"Fixed Rate of 2 seconds"), new Date(), 3000);
RunnableTask
将在当前时间之后3000毫秒运行。
5. 使用CronTrigger
进行调度
我们使用CronTrigger
根据cron表达式安排任务:
CronTrigger cronTrigger
= new CronTrigger("10 * * * * ?");
我们可以使用提供的触发器按照特定的节奏或计划运行任务:
taskScheduler.schedule(new RunnableTask("Cron Trigger"), cronTrigger);
在这种情况下,RunnableTask
将在每分钟的第10秒执行。
6. 使用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的返回语句之前添加两行代码:
periodicTrigger.setFixedRate(true);
periodicTrigger.setInitialDelay(1000);
我们使用setFixedRate
方法以固定速率安排任务,而不是固定延迟。然后使用setInitialDelay
方法设置首次可运行任务的初始延迟。
7. 总结
在这篇简短的文章中,我们学习了如何使用Spring对任务的支持进行任务调度。
我们演示了如何根据固定延迟、固定速率和特定触发器运行任务。
如往常一样,代码作为Maven项目可以在GitHub上找到:在这里。