在启动类添加注解
@SpringBootApplication
@EnableScheduling
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
在定时执行的方法之上添加注解(类上需要有@Component注解)
@Component
public class Task1 {
@Scheduled(cron ="*/1 * * * * ?")
public void sayWord() {
System.out.println("world");
}
}
在启动类添加注解
@SpringBootApplication
@EnableScheduling
@EnableAsync // 开启多线程
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
在定时执行的方法之上添加注解(类上需要有@Component注解)
@Component
public class Task1 {
@Async
@Scheduled(cron ="*/1 * * * * ?")
public void sayWord() {
System.out.println("world");
}
}
语法格式:"秒域 分域 时域 日域 月域 周域 年域"(一般是六个或七个字段)
取值范围
域名 | 可取值 | 可取符号(仅列部分常用) |
秒域 | 0~59的整数 | * - , / |
分域 | 0~59的整数 | * - , / |
时域 | 0~23的整数 | * - , / |
日域 | 1~31的整数 | * - , / ? L |
月域 | 1~12的整数或JAN~DEC | * - , / |
周域 | 1~7的整数或SUN~SAT | * - , / ? L # |
年域 | 1970~2099的整数 | * - , / |
指定两次任务执行的时间间隔(毫秒),前一个任务结束与下一个任务开始的间隔
如:@Scheduled(fixedDelay = 5*1000 ),表示第一个任务执行结束,开始计时,过5秒后,开始第二次执行。
指定两次任务执行的时间间隔(毫秒),前一个任务开始与下一个任务开始的间隔。
如:@Scheduled(fixedRate= 5*1000 ),表示第一个任务开始执行,开始计时,过5秒后,开始第二次执行。
第一次延迟执行的时间
如:@Scheduled(initialDelay=1000, fixedRate=5000) //第一次延迟1秒后执行,之后按fixedRate的规则每5秒执行一次
在启动类必须加上@EnableScheduling注解
@SpringBootApplication
@EnableScheduling
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
实现SchedulingConfigurer并重写configureTasks方法
@Component
@EnableScheduling
public class MyTask implements SchedulingConfigurer {
@Autowired
protected CronMapper cronMapper;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.addTriggerTask(() -> process(),
triggerContext -> {
String cron = cronMapper.getCron(1);
if (cron.isEmpty()) {
System.out.println("cron is null");
}
return new CronTrigger(cron).nextExecutionTime(triggerContext);
});
}
// 定时任务
private void process() {
//TODO
System.out.println("执行动态定时任务:"+new Date(System.currentTimeMillis()));
}
}
任务调度接口 TaskScheduler,它提供了多种方法来调度将来某个时间点要运行的任务。
schedule(Runnable task, Trigger trigger);
指定一个触发器执行定时任务。可以使用CronTrigger来指定Cron表达式,执行定时任务。schedule(Runnable task, Date startTime);
指定一个具体时间点执行定时任务,可以动态的指定时间,开启任务。只执行一次。scheduleAtFixedRate(Runnable task, long period);
立即执行,循环任务,指定一个执行周期(毫秒计时)
不管上一个周期是否执行完,到时间下个周期就开始执行scheduleAtFixedRate(Runnable task, Date startTime, long period);
指定时间开始执行,循环任务,指定一个间隔周期(毫秒计时)
不管上一个周期是否执行完,到时间下个周期就开始执行scheduleWithFixedDelay(Runnable task, long delay);
立即执行,循环任务,指定一个间隔周期(毫秒计时)
上一个周期执行完,等待delay时间,下个周期开始执行scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
指定时间开始执行,循环任务,指定一个间隔周期(毫秒计时)
上一个周期执行完,等待delay时间,下个周期开始执行
TaskScheduler有4个实现类: ConcurrentTaskScheduler、DefaultManagedTaskScheduler、ThreadPoolTaskScheduler、TimerManagerTaskScheduler。
以当前线程执行任务,单个线程方式执行定时任务,适用于简单场景。
示例:
ConcurrentTaskScheduler taskScheduler = new ConcurrentTaskScheduler();
// 执行一次
taskScheduler.execute(() -> log.info(Thread.currentThread().getName() + "执行一次"));
// 周期性执行
taskScheduler.schedule(() -> log.info(Thread.currentThread().getName() + "多次执行"), new CronTrigger("0/2 * * * * ?"));
以当前线程执行任务,这是ConcurrentTaskScheduler的子类,添加了JNDI的支持。和ConcurrentTaskScheduler一样的用法,需要使用JNDI可以单独设置。
提供线程池管理的调度器:多线程定时任务执行,实现了TaskExecutor接口,从而使的单一的实例可以尽可能快地异步执行。可以设置执行线程池数(默认一个线程)。
ThreadPoolTaskScheduler 的方法:
setPoolSize
设置线程池大小,最小为1,默认情况下也为1;
setErrorHandler
设置异常处理器。
getScheduledThreadPoolExecutor
获取ScheduledExecutor,默认是ScheduledThreadPoolExecutor类型。
getActiveCount
获取当前活动的线程数
execute
提交执行一次的任务
submit\submitListenable
提交执行一次的任务,并且返回一个Future对象供判断任务状态使用。
示例:
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(6);
taskScheduler.initialize(); // 务必调用此方法来手动启动
// 执行一次
taskScheduler.execute(new Runnable() {
@Override
public void run() {
log.info(Thread.currentThread().getName() + "执行一次");
}
});
// 周期性执行
taskScheduler.schedule((new Runnable() {
@Override
public void run() {
log.info(Thread.currentThread().getName() + "多次执行");
}
}), new CronTrigger("0/2 * * * * ?"));
同时继承CommonJ中的TimerManager接口。在使用CommonJ进行调度时使用。
ScheduledFuture:通过cancle和读取isCancelled结果来退出
调用完成之后会返回一个scheduledFuture,这个就是当前的任务调度器,停止的时候需要找到这个调度器,用这个调用器来终止。
boolean cancelled = scheduledFuture.isCancelled(); // 用来判断是否已经取消
if(!cancelled ){
scheduledFuture.cancel(true);// 用来将当前的任务取消
}