摘要
实现定时任务有多种方式
Timer实现定时任务
Timer是最简单的定时任务实现方式。
创建定时任务过程如下:
- 创建任务类继承TimerTask,并实现run方法
- 创建Timer类对象执行任务
代码如下:
// 创建任务对象
TimerTask task = new TimerTask(){
@Override
public void run(){
// 定时任务逻辑
}
};
// 创建Timer并执行任务
Timer timer = new Timer();
timer.schedule(task,0,1000);
说明:一个TimerTask对象只能被一个Timer执行,但一个Timer可以执行多个TimerTask
常用API说明
TimerTask
- public boolean cancel() 取消任务
Timer
- public void cancel() 取消全部任务
- public int purge() 清空任务队列,并返回清空的数量
- public void schedule(TimerTask task, long delay) 延迟delay毫秒执行任务
- public void schedule(TimerTask task, Date time) 在时间time时执行任务
- public void schedule(TimerTask task, long delay, long period) 延迟delay毫秒执行,并周期性执行任务
- public void schedule(TimerTask task, Date firstTime, long period) 在时间time时执行,并周期性执行任务
- public void scheduleAtFixedRate(TimerTask task, long delay, long period) 延迟delay毫秒执行,并周期性执行任务
- public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) 在时间time时执行,并周期性执行任务
schedule和scheduleAtFixedRate的区别:
- schedule:当某次执行任务出现停顿,如Thread.sleep(),会导致后面的执行推迟
- scheduleAtFixedRate:当某次执行任务出现停顿,不会影响后面任务的执行计划
注意:任务执行完成或取消任务后,Timer和TimerTask的回收存在一定的延时性,会导致线程资源不能及时回收,可以通过手动调用System.gc()及时回收。
ScheduledExecutorService实现定时任务
通过线程池实现定时任务
ScheduledExecutorService executor = new Executor.newSingleThreadScheduledxecutor();
executor.scheduledAtFixRate(()->System.out.println("执行任务"),0,1,TimeUnit.SECONDS);
使用与Timer类似,详细介绍略。
Spring Task实现定时任务
如何开启定时任务
- 通过@EnableScheduling开启SpringBoot计划任务
- 使用@Scheduled标记任务计划
@Slf4j
@EnableScheduling // 1 加入该注解表示开启任务
@Component
public class Task {
@Scheduled(cron = "0/1 * * * * *") // 2 使用该注解标记方法定时执行,通过参数控制定时策略
public void task() {
log.info("定时任务。执行时间:{}。", LocalDateTime.now());
}
}
启动项目可以看到如下输出
2018-07-21 16:42:05.009 INFO 1019 --- [pool-1-thread-1] com.ly.Task : 定时任务。执行时间:2018-07-21T16:42:05.009。
2018-07-21 16:42:06.004 INFO 1019 --- [pool-1-thread-1] com.ly.Task : 定时任务。执行时间:2018-07-21T16:42:06.004。
2018-07-21 16:42:07.005 INFO 1019 --- [pool-1-thread-1] com.ly.Task : 定时任务。执行时间:2018-07-21T16:42:07.005。
2018-07-21 16:42:08.005 INFO 1019 --- [pool-1-thread-1] com.ly.Task : 定时任务。执行时间:2018-07-21T16:42:08.004。
2018-07-21 16:42:09.002 INFO 1019 --- [pool-1-thread-1] com.ly.Task : 定时任务。执行时间:2018-07-21T16:42:09.002。
2018-07-21 16:42:10.003 INFO 1019 --- [pool-1-thread-1] com.ly.Task : 定时任务。执行时间:2018-07-21T16:42:10.003。
以上任务都是同一线程执行的,可以通过标记异步任务实现多线程执行。
@Scheduled注解有三个属性控制定时
- fixedRate:固定频率
- fixedDelay:固定频率,可以配合initialDelay属性控制延迟执行
- cron:通过表达式控制,可以到http://cron.qqe2.com/生成表达式
Quartz
Spring Task针对大部分情况已经足够使用,Quartz暂时没有用过。