上一篇 <<
实现方案
多线程形式、timetask、线程池、Springboot的Schedule注解形式、Quartz。
Spring batch是把Quartz框架做了封装,Schedule底层也是用了Quartz框架。
框架对比
定时任务框架 | Cron表达式 | 固定间隔执行 | 固定频率执行 | 任务持久化 | 开发难易度 |
---|---|---|---|---|---|
JDK TimerTask | 不支持 | 支持 | 支持 | 不支持 | 一般 |
Spring Schedule | 支持 | 支持 | 支持 | 不支持 | 简单 |
Quartz | 支持 | 支持 | 支持 | 支持 | 难 |
1.多线程形式
/**
* 多线程方式
*/
public class ThreadTask {
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(1000);
System.out.println("定时任务触发...");
} catch (InterruptedException e) {
}
}
}
}).start();
}
}
2.timetask多线程形式
多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其他任务便会自动终止运行,使用ScheduleExecutorService则没有这个问题。
public class TimerTaskDemo {
public static void main(String[] args) {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "定时任务触发");
}
};
Timer timer = new Timer();
// 天数
long delay = 0;
// 耗秒数
long period = 1000;
timer.scheduleAtFixedRate(timerTask, delay, period);
}
}
3.线程池形式
public class ScheduledExecutorServiceDemo {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("定时任务触发..");
}
};
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
scheduledExecutorService.scheduleAtFixedRate(runnable, 1, 1, TimeUnit.SECONDS);
}
}
4.SpringBoot的Schedule形式
@Component
public class UserScheduled {
@Scheduled(cron = "0/1 * * * * *")
public void taskUserScheduled() {
System.out.println("定时任务触发...");
}
}
@SpringBootApplication
@EnableScheduling
public class T {
public static void main(String[] args) {
SpringApplication.run(T.class);
}
}
5.Quartz形式
org.quartz-scheduler
quartz
2.2.1
org.quartz-scheduler
quartz-jobs
2.2.1
public class QuartzTest {
public static void main(String[] args) throws SchedulerException {
//1.创建Scheduler的工厂
SchedulerFactory sf = new StdSchedulerFactory();
//2.从工厂中获取调度器实例
Scheduler scheduler = sf.getScheduler();
//3.创建JobDetail
JobDetail jb = JobBuilder.newJob(MyJob.class)
.withDescription("this is a ram job") //job的描述
.withIdentity("ramJob", "ramGroup") //job 的name和group
.build();
//任务运行的时间,SimpleSchedle类型触发器有效
long time = System.currentTimeMillis() + 3 * 1000L; //3秒后启动任务
Date statTime = new Date(time);
//4.创建Trigger
//使用SimpleScheduleBuilder或者CronScheduleBuilder
Trigger t = TriggerBuilder.newTrigger()
.withDescription("")
.withIdentity("ramTrigger", "ramTriggerGroup")
//.withSchedule(SimpleScheduleBuilder.simpleSchedule())
.startAt(statTime) //默认当前时间启动
.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")) //两秒执行一次
.build();
//5.注册任务和定时器
scheduler.scheduleJob(jb, t);
//6.启动 调度器
scheduler.start();
}
}
/**
* 单独文件
*/
public class MyJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("quartz MyJob date:" + System.currentTimeMillis());
}
}
推荐阅读:
<<<传统任务调度存在的缺陷
<<<如何保证我们的定时任务只会触发一次
<<<定时任务宕机后如何处理
<<<分布式任务调度平台的特点
<<
<<