定时任务,顾明思议就是在不需要人工干预的前提下,预先设定好程序执行频率或者执行时间。与传统的触发式请求响应最大的区别在于,定时任务需要在程序设计时自动进行响应调用。
常用的几种定时任务实现方式如下:
1.Timer:一种java自带的java.util.Timer类,改类调度一个java.util.TimerTask任务,使用该方法会让程序以一定的频率去执行,但是不能指定时间下运行。该种方法在我最开始接触java编程语言的时候使用过,目前已经基本被我废弃,废话不多说了,直接上demo代码。
public class TestTimer {
public static void main(String[] args) {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("task run:"+ new Date());
}
};
Timer timer = new Timer();
//安排指定的任务在指定的时间开始进行重复的固定延迟执行。这里是每3秒执行一次
timer.schedule(timerTask,10,3000);
}
}
2.ScheduledExecutorService:改类是基于线程池设计的定时任务类,每个调度任务分配到线程池中的一个线程去执行,可以并发执行。
public class TestScheduledExecutorService {
public static void main(String[] args) {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
// 参数:1、任务体 2、首次执行的延时时间
// 3、任务执行间隔 4、间隔时间单位
service.scheduleAtFixedRate(()->System.out.println("task ScheduledExecutorService "+new Date()), 0, 3, TimeUnit.SECONDS);
}
}
3.今年开始我慢慢地喜欢上了注解的方式,再加上使用过了spring boot框架之后,越发觉得能用注解解决的问题就用注解解决,这是因为它真心方便。这一种方式是我极力推崇的,也是我在目前项目中经常使用的用于定时任务处理的方法。先上代码再说。
public class ScheduledService {
@Scheduled(fixedDelay = 60000) //1分钟执行一次
public void serviceStatusGet(){
log.info(String.format("===第%s次开始执行应用状态数据抽取服务,当前时间为:%s", count2, dateFormat.format(new Date())));
svcStatusUtil.getServiceStatus();
log.info(String.format("===第%s次执行结束应用状态数据抽取服务,当前时间为:%s", count2, dateFormat.format(new Date())));
count2++;
}
@Scheduled(cron = "0 0 12 * * ?") //每天中午12点触发
public void serviceStatusGet2(){
log.info(String.format("===第%s次开始执行应用状态数据抽取服务,当前时间为:%s", count2, dateFormat.format(new Date())));
svcStatusUtil.getServiceStatus();
log.info(String.format("===第%s次执行结束应用状态数据抽取服务,当前时间为:%s", count2, dateFormat.format(new Date())));
count2++;
}
}
该定时任务非常简易,只需要在要实现的方法上添加@Scheduled(*)注解即可,常用的可以分为两类,第一种属于按照时间频率定时任务@Scheduled(fixedDelay=6000),另一种为设置固定时间点执行定时任务@Scheduled(“0 0 12 * * ?” )。具体的其它类型可以想看对应的api。总之,在使用过上面几种定时任务处理的经验来看,直接使用@@Scheduled注解的方式应该是最方便的。