本文共 4664 字,大约阅读时间需要 15 分钟。
在项目中我们经常需要使用定时任务,实现定时任务的方案主要如下:
使用 JDK 的 Timer 和 TimerTask 实现
可以实现简单的间隔执行任务,无法实现按日历去调度执行任务。
使用 Quartz 实现
Quartz 是一个异步任务调度框架,功能丰富,可以实现按日历调度。
使用 Spring Task 实现
Spring 3.0 后提供 Spring Task 实现任务调度,支持按日历调度,相比 Quartz 功能稍简单,但是在开发基本够用,支持注解编程方式。
实现步骤:
代码:
@Componentpublic class MyTask { SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss"); @Scheduled(cron = "0/5 * * * * *") // 每隔 5 秒执行一次 public void task1() { System.out.println("定时任务1开始:" + sdf.format(System.currentTimeMillis())); try { Thread.sleep(3000); // 定时任务执行 3 秒 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("定时任务1结束:" + sdf.format(System.currentTimeMillis())); } }
运行结果:
定时任务1开始:2020/10/16 05:03:40定时任务1结束:2020/10/16 05:03:43定时任务1开始:2020/10/16 05:03:45定时任务1结束:2020/10/16 05:03:48定时任务1开始:2020/10/16 05:03:50定时任务1结束:2020/10/16 05:03:53...
参考 task1 方法的的定义方法,再定义 task2 方法,此时共用两个任务方法。
代码:
@Componentpublic class MyTask { SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss"); @Scheduled(cron = "0/5 * * * * *") //每隔 5 秒执行一次 public void task1() { System.out.println("定时任务1开始:" + sdf.format(System.currentTimeMillis())); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("定时任务1结束:" + sdf.format(System.currentTimeMillis())); } @Scheduled(cron = "0/5 * * * * *") //每隔 5 秒执行一次 public void task2() { System.out.println("定时任务2开始:" + sdf.format(System.currentTimeMillis())); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("定时任务2结束:" + sdf.format(System.currentTimeMillis())); } }
运行结果:
定时任务1开始:2020/10/16 05:11:00定时任务1结束:2020/10/16 05:11:03定时任务2开始:2020/10/16 05:11:03定时任务2结束:2020/10/16 05:11:06定时任务1开始:2020/10/16 05:11:06定时任务1结束:2020/10/16 05:11:09定时任务1开始:2020/10/16 05:11:10定时任务1结束:2020/10/16 05:11:13定时任务2开始:2020/10/16 05:11:13定时任务2结束:2020/10/16 05:11:16...
cron 表达式包括 6 部分:
特殊字符介绍:
例子:
Spring Task 默认是单线程的,上面的两个定时任务使用的都是同一个线程,所以会串行执行任务。但有时我们也需要并行执行多个不同的任务,这时就需要使用多线程技术了,我们可以配置线程池来实现多线程调度任务。
代码:
创建配置类,创建线程池对象并将其加入 IOC 容器
@Configuration@EnableSchedulingpublic class ScheduleConfig { @Bean public ThreadPoolTaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.initialize(); //初始化线程池 scheduler.setPoolSize(2); //线程池容量 return scheduler; }}
任务类不变
@Componentpublic class MyTask { SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss"); @Scheduled(cron = "0/5 * * * * *") //每隔 5 秒执行一次 public void task1() { System.out.println("定时任务1开始:" + sdf.format(System.currentTimeMillis())); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("定时任务1结束:" + sdf.format(System.currentTimeMillis())); } @Scheduled(cron = "0/5 * * * * *") //每隔 5 秒执行一次 public void task2() { System.out.println("定时任务2开始:" + sdf.format(System.currentTimeMillis())); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("定时任务2结束:" + sdf.format(System.currentTimeMillis())); } }
将 @EnableScheduling 添加到此配置类上,SpringBoot 启动类上不用再添加 @EnableScheduling
运行结果:
定时任务2开始:2020/10/16 11:52:10定时任务1开始:2020/10/16 11:52:10定时任务1结束:2020/10/16 11:52:13定时任务2结束:2020/10/16 11:52:13定时任务2开始:2020/10/16 11:52:15定时任务1开始:2020/10/16 11:52:15...
转载地址:http://ffjvb.baihongyu.com/