java实现定时任务 Timer springTask cron表达式
1 实现方式
1.1 JDK自带
Timer 实现比较简单的定时,无线程池
Executos 带线程池
1.2 第三方
quartz 功能很强大,网上帖子很多,可以完成定时任务功能(自己翻帖子能实现)
springTask
2 Timer
2.1 延迟指定时间后执行
直接把下面的代码复制到项目的类中,就可以用了,不能指定固定的时间间隔一直执行这个事
public static void main(String[] args) throws Exception {
//1.创建timer
Timer timer = new Timer();
//2.创建任务
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("11111111111111");
System.out.println("1111111-1111111");
}
};
//3000代表延迟3秒执行,1000代表间隔1秒执行一次
//3.设置执行时间
timer.schedule(timerTask,3000,1000);
//4.睡眠5秒
Thread.sleep(5000);
//5.停止
timer.cancel();
}
2.2 指定具体时间点执行
代码如下
public static void main(String[] args) throws Exception {
//1.创建timer
Timer timer = new Timer();
//2.创建任务
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("11111111111111");
System.out.println("1111111-1111111");
}
};
//3.设置执行时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = "2021-7-11 16:08:30";
Date parse = sdf.parse(str);
timer.schedule(timerTask,parse);
}
2.3 Timer的缺点 无线程池
如果没有线程池,那么在循环使用时,每一个循环都会新增一条线程,如果线程太多,就会导致项目崩溃
示例代码
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimerDemo {
public static void main(String[] args) throws Exception {
//每一个循环都会新增一条线程
for (int i=0;i<100;i++){
//1.创建timer
Timer timer = new Timer();
//2.创建任务
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
System.out.println("11111111111111");
System.out.println("1111111-1111111");
}
};
//0 代表没有延迟 立即执行
timer.schedule(timerTask,0);
}
}
}
效果:
3 ScheduledThreadPoolExecutor
通过查看父子类结构,可以看到ScheduledThreadPoolExecutor是Executos接口的一个实现类
简单了解一下就好,下面的代码可以直接复制
public static void main(String[] args) throws Exception {
//看名字带ThredPool就知道带线程池 注意 这个类所在包是java自己的 不是别的包的
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(30);
for (int i = 0 ;i<100;i++){
executor.schedule(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
System.out.println("execute task ...");
}
},5,TimeUnit.SECONDS);//5 配合后面的TimeUnit.SECONDS代表延迟5秒执行
}
}
4 springTask(主要使用)
4.1 简单介绍
springTask属于spring框架,本质是对JDK执行器和调度器进行封装
4.1 延迟指定时间后执行
public static void main(String[] args) throws Exception {
//创建带线程池的调度器
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
//手动初始化
taskScheduler.initialize();
//设置线程池
taskScheduler.setPoolSize(30);
System.out.println(taskScheduler);
taskScheduler.schedule(new Runnable() {
@Override
public void run() {
System.out.println("sssss");
}
},new Date(System.currentTimeMillis()+2000));//在系统当前时间的基础上延迟2000毫秒执行
}
4.2 指定具体时间执行
public static void main(String[] args) throws Exception {
//创建带线程池的调度器
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
//手动初始化
taskScheduler.initialize();
//设置线程池
taskScheduler.setPoolSize(30);
System.out.println(taskScheduler);
taskScheduler.schedule(new Runnable() {
@Override
public void run() {
System.out.println("sssss");
}
},new CronTrigger("0/5 * * * * *"));//这串字符串是cron表达式 代表每隔5秒执行一次
}
5 cron表达式
比如"0/5 * * * * *"
分别代表 延迟时间/秒 分 时 日 月 年
可以理解为 延迟时间/间隔时间
延迟时间以秒为单位,当延迟时间设置为0时代表没有延迟
间隔时间可以具体设置年月日时分秒
因此corn表达式"0/5 * * * * *"代表无论无论哪年哪月哪日,每间隔5秒,就0延迟执行一次方法
cron表达式一般通过注解使用,而不是像上面的代码那样使用
6 cron表达式的一些格式案例
查看官方源码的注释
从上往下
①每天整点就会执行一次 类似报时
②每十秒钟执行一次
③每天的8、9、10三个时刻的整点执行一次 注意“-”的使用 这代表范围
④每天6点和19点的整点执行一次 注意“~”
⑤每天的8点开始 间隔30分钟执行一次
⑥每周工作日的9点到17点的整点执行一次
⑦每年圣诞节的午夜0点执行一次