文章目录

  • 摘要
  • Timer实现定时任务
  • ScheduledExecutorService实现定时任务
  • Spring Task实现定时任务
  • Quartz


摘要

实现定时任务有多种方式

Timer实现定时任务

Timer是最简单的定时任务实现方式。

创建定时任务过程如下:

  1. 创建任务类继承TimerTask,并实现run方法
  2. 创建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实现定时任务

如何开启定时任务

  1. 通过@EnableScheduling开启SpringBoot计划任务
  2. 使用@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暂时没有用过。