1、开启支持,在启动类上面加个注解:@EnableScheduling
@SpringBootApplication
@EnableScheduling
public class Application{
public static void mian(String[] args){
SpringApplication.run(Application.class,args);
}
}
2、定时的两种类型:
a. 间隔执行
/**
* 需求:每隔5秒执行一次
* 间隔定时任务:2种写法
*/
// @Scheduled(cron = "0/5 * * * * ?")
@Scheduled(fixedRate = 5*1000)
public void scheduledTest() {
System.err.println("每隔5秒执行一次: "
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
结果输出如下:
每隔5秒执行一次: 2019-07-24 09:48:03
每隔5秒执行一次: 2019-07-24 09:48:08
每隔5秒执行一次: 2019-07-24 09:48:13
每隔5秒执行一次: 2019-07-24 09:48:18
每隔5秒执行一次: 2019-07-24 09:48:23
每隔5秒执行一次: 2019-07-24 09:48:28
fixedRate和fixedDelay的区别:
fixedDelay:它的周期间隔是根据上次任务结束的时间开始计时的。比如一个方法上设置了fixedDelay=5*1000,那么当该方法某一次执行结束后,开始计算时间,当时间达到5秒,就开始再次执行该方法。
fixedRate:它的周期间隔是根据上次任务开始的时候计时的。比如当方法上设置了fiexdRate=5*1000,执行该方法所花的时间是2秒,那么3秒后就会再次执行该方法。并且此方法会阻塞,具体解决方案是利用线程池和多线程
b. 定时执行
/**
* 需求:定时执行
* 每天3点执行
*/
// cron = "* * * * * ?":秒 分 时 日 月 周 年
@Scheduled(cron = "0 0 3 * * ?")
public void scheduledTest1() {
System.out.println("每天3点执行: " new Date());
}
参数解释:
* cron = "* * * * * ?":秒 分 时 日 月 周 年
* 第一位,表示秒,取值 0-59
* 第二位,表示分,取值 0-59
* 第三位,表示小时,取值 0-23
* 第四位,日期,取值 1-31
* 第五位,月份,取值 1-12
* 第六位,星期几,取值 1-7
* 第七位,年份,可以留空,取值 1970-2099
* (*) 星号:可以理解为“每”的意思,每秒、没分
* (?) 问好:只能出现在日期和星期这两个位置,表示这个位置的值不确定
* (-) 表达一个范围,如在小时字段中使用 10-12 ,表示从10点到12点
* (,) 逗号,表达一个列表值,如在星期字段中使用 1,2,4 ,则表示星期一、星期二、星期四
* (/) 斜杠,如 x/y ,x是开始值,y是步长,如在第一位(秒)使用 0/15,表示从0秒开始,每15秒
*
* **********************************************************************************
*
* 官方解释:
* 0 0 3 * * ? 每天 3 点执行
* 0 5 3 * * ? 每天 3 点 5 分执行
* 0 5 3 ? * * 每天 3 点 5 分执行
* 0 5/10 3 * * ? 每天 3 点 5 分,15 分,25 分,35 分,45 分,55 分这几个点执行
* 0 10 3 ? * 1 每周星期天的 3 点10 分执行,注:1 表示星期天
* 0 10 3 ? * 1#3 每个月的第三个星期的星期天 执行,#号只能出现在星期的位置
* 注:第六位(星期几)中的数字可能表达不太正确,可以使用英文缩写来表示,如:Sun
3、直接使用java的Timer()方法,重写内部run()方法即可
public static void main(String[] args) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 此方法一旦异常,影响其他的定时任务,耦合性高,不建议使用
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
long l = System.currentTimeMillis();
// TODO Auto-generated method stub
System.out.println("测试java定时任务一秒发送一次:"+simpleDateFormat.format(l));
}
}, 0, 1000);// 延迟0秒,周期1秒
}
输出如下:
测试java定时任务一秒发送一次:2020-03-10 17:15:38
测试java定时任务一秒发送一次:2020-03-10 17:15:39
测试java定时任务一秒发送一次:2020-03-10 17:15:40
4、使用java的ScheduledThreadPoolExecutor()多线程方法
public static void main(String[] args) {
// 建议使用此方法,线程池,无耦合性
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 建议使用此方法,线程池,无耦合性
ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(1);
pool.scheduleAtFixedRate(() -> {
long l = System.currentTimeMillis();
System.out.println("ScheduledThreadPool is run!"+simpleDateFormat.format(l));
}, 0, 2, TimeUnit.SECONDS); // 延时0秒,周期2秒
}
输出如下:
ScheduledThreadPool is run!2020-03-14 11:16:33
ScheduledThreadPool is run!2020-03-14 11:16:35
ScheduledThreadPool is run!2020-03-14 11:16:37