说要有一个定时器就好了,到点了自动督促我们学习或者干点别的
于是花了大半天的百度,我终于研究出来了简单的定时器,今天就介绍我研究的简单的三种
一、Timer
要是要实现定时任务,最先想到的肯定是java自带的类,就是Timer类,它在JDK类库中主要负责计划任务的功能,也就是在指定的时间开始执行某一个任务,或者进行一些周期性的工作。
无论什么java项目我们都可以直接使用Timer来实现定时任务
我们先看代码
package com.mystep.step.util;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* @author step
* @date 2021年07月24日 20:44
*/
public class StepTimerTask {
public static void main(String[] args) {
// 定义一个任务
TimerTask stepTimerTask = new TimerTask() {
@Override
public void run() {
System.out.println("运行定时Step任务:" + new Date());
System.out.println("运行Step完毕");
}
};
// 计时器
Timer timer = new Timer();
// 添加执行任务(延迟1s执行,每三秒执行一次)
timer.schedule(stepTimerTask, 1000, 3000);
}
}
使用方法相对来说很简单,就是先用TimerTask创建一个任务,在其中重写run方法,在其中就正常编写我们的定时任务。
其中Timer类中的shedule 我们上面用的第一个参数就是要定时的任务,第二个参数就是延时多长时间,第三个参数就是时间间隔。
运行结果
优缺点
优点
优点是简单,就是此方法是由java原生支持的,在任何项目中都可以使用,而且使用简单快捷
缺点
- 任务执行时间长影响其他任务
- 当一个任务执行时间过长时,会影响其他任务的调度。 任务异常影响其他任务
- 我们使用Timer类实现定时任务时,当一个任务抛出异常,其他任务也会终止运行。
二、 ScheduleExecutorService
ScheduleExecutorService是JDK1.5自带的API,我们可以使用它来实现定时任务的功能,也就是说Timer可以实现的使用ScheduleExecutorService也可以轻松实现,而且还解决了Timer存在的问题。
代码
package com.mystep.step.util;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @author step
* @date 2021年07月24日 21:38
*/
public class StepScheduleExecutorService {
public static void main(String[] args) {
// 创建任务队列,并且设置线程数量为10
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
// 执行任务
scheduledExecutorService.scheduleAtFixedRate(()->{
System.out.println("执行定时任务"+ new Date());
System.out.println("执行结束");
},1,3, TimeUnit.SECONDS);
}
}
运行结果
优点
其相对于Timer来说最大的改变就是任务超时执行时,不会影响另外的任务按时执行,虽然依旧会影响自己的任务按时执行。而且就算发生异常,也不会对其他任务产生影响。
三、 Spring Task(在项目里我感觉实际点)
前面的两个方法是都JKD自带的,接下来我们要介绍的Spring Task就是基于Spring框架的,其直接使用了Spring Framework自带的定时任务,相比于前两种方法来说,也可以轻松的指定具体时间来执行任务。
定时任务步骤
以Spring Boot为例,实现定时任务只需要两步:
- 开启定时任务
- 添加定时任务
开启定时任务
开启定时任务,只需要在Spring Boot的启动类上声明@EnableScheduling即可,代码如下所示
package com.mystep.step;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling // 开启定时任务
public class StepApplication {
public static void main(String[] args) {
SpringApplication.run(StepApplication.class, args);
}
}
添加定时任务
定时任务的添加只需要使用@Schedule注解标注即可,如果有多个定时任务,可以常见多个@Scheduled注解标注的方法,代码如下所示:
package com.mystep.step.util;
import com.mystep.step.service.StudentWarnService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* @author step
* @date 2021年07月24日 14:15
*/
@Component
public class WarnUtil {
@Autowired
private StudentWarnService studentWarnService;
@Scheduled(cron = "*/5 * * * * ?")
//表示每过五秒打印一下任务。
public void doTask(){
System.out.println("dingshi任务");
}
}
需要注意的定时任务是自动触发的无需手动干预,也就是说SpringBoot启动后会自动加载并执行定时任务。
Cron表达式
在上面我们使用Spring Task的实现中我们使用到了Cron表达式,用来声明执行的频率和规则Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:
- Seconds Minutes Hours DayofMonth Month DayofWeek Year
- Seconds Minutes Hours DayofMonth Month DayofWeek
最懒的方式,附上cron表达式在线生成器,只做分享,可用可不用,我百度的
我此次做的定时任务,记录下
没天晚上十点更改数据库里某个东西,给学习的人警告
import com.mystep.step.common.constant.GlobalConstant;
import com.mystep.step.entity.StudentWarn;
import com.mystep.step.service.StudentWarnService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author step
* @date 2021年07月24日 14:15
*/
@Component
public class WarnUtil {
@Autowired
private StudentWarnService studentWarnService;
@Scheduled(cron = "00 00 22 * * ?")
public void doTask(){
// StudentWarn studentWarn=new StudentWarn();
// System.out.println("dingshi任务");
List<StudentWarn> stuWarn=studentWarnService.list();
for (int i=0;i<stuWarn.size();i++){
if (stuWarn.get(i).getCreateTime().plusMonths(GlobalConstant.STUDY_MONTH_TIME).isBefore(LocalDateTime.now())){
if (stuWarn.get(i).getWarn().equals("无")){
stuWarn.get(i).setWarn("学习时间太长了休息一下");
studentWarnService.updateById(stuWarn.get(i));
}
// studentWarn.getId()=stuWarn.get(i).getId();
}
}
}
}