Java定时任务
java.util.Time类, java.util.TimerTask类
开源,功能强大,使用起来稍显复杂
public static void main(String[] args) {
try {
//调度器
Scheduler defaultScheduler = StdSchedulerFactory.getDefaultScheduler();
defaultScheduler.start();
// defaultScheduler.pauseTriggers(triggerKeyGroupMatcher);
//任务详情 一个任务可以被多个触发器调度
JobDetail job = newJob(HelloJob.class)
.withIdentity("job1", "group1")//任务名称,任务组名称
.build();
JobDetail job2 = newJob(HelloJob.class)
.withIdentity("job2", "group1")//任务名称,任务组名称
.build();
//触发器 一个触发器只能调度一个任务
Trigger trigger = newTrigger()
.withIdentity("trigger1", "group1")//调度器名称,调度器组名称
.startNow()//马上启动
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(1)//每隔5秒出发一次
.repeatForever())//一直执行
.build();
//触发器1
Trigger trigger2 = newTrigger()
.withIdentity("trigger2", "group1")//调度器名称,调度器组名称
.startNow()//马上启动
.forJob("job2", "group1")//指定任务
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(3)//每隔5秒出发一次
.withRepeatCount(1)) //指定执行次数,只执行一次
.build();
//把触发器和任务交给调度器,调度器会按照触发器配置的规则去触发任务
defaultScheduler.scheduleJob(job, trigger);
defaultScheduler.scheduleJob(job2, trigger2);
TimeUnit.SECONDS.sleep(3);
defaultScheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
//调度器
Scheduler defaultScheduler = StdSchedulerFactory.getDefaultScheduler();
defaultScheduler.start();
// defaultScheduler.pauseTriggers(triggerKeyGroupMatcher);
//任务详情 一个任务可以被多个触发器调度
JobDetail job = newJob(HelloJob.class)
.withIdentity("job1", "group1")//任务名称,任务组名称
.build();
//触发器 一个触发器只能调度一个任务
Trigger trigger = newTrigger()
.withIdentity("trigger1", "group1")//调度器名称,调度器组名称
.startNow()//马上启动
.withSchedule(
/***
*
*
* @auther wangxiang
* @date 2022/8/9 13:45
* 秒 分 时 日 月 星期 年
* 0-5表示 0到5秒每秒都执行
* 0,5表示 0和5秒各执行一次
* 0/5表示 每5秒执行一次
*
*
* ?表示不知道
* L表示最后一天(日和周)
* W表示工作日
* 年是可选的
*/
//*/5表示 每5秒执行一次
CronScheduleBuilder.cronSchedule("* * * * * ? *")
)
.build();
//获取当前时间30天后的时间
LocalDateTime localDateTime = LocalDateTime.now().plus(30,ChronoUnit.DAYS);
//把触发器和任务交给调度器,调度器会按照触发器配置的规则去触发任务
defaultScheduler.scheduleJob(job, trigger);
TimeUnit.SECONDS.sleep(3);
defaultScheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Spring Task
spring3.0以后自带task调度工具,比Quartz更加的简单方便
实现方式:
纯XML配置方式
-
简单的定时任务
实现业务功能+配置定时规则
initial-delay:设置服务器启动完毕后等多少毫秒后开始执行定时任务
fixed-delay:每隔多少毫秒执行一次
-
复杂定时任务
cron表达式
全注解方式
-
在业务方法上提供注解
-
开启注解支持
spring boot 实现定时任务
总结
Quartz 默认多线程异步执行 单个任务时,在上一个调度未完成时,下一个调度时间到时,会另起一个线程开始新的调度。业务繁忙时,一个任务会有多个调度,可能导致数据处理异常。 多个任务时,任务之间没有直接影响,多任务执行的快慢取决于CPU的性能 触发方式 : (1)SimpleTrigger (2)CronTrigger 需要在配置文件中实现配置Job 能被集群实例化,支持分布式部署 使用JobStoreCMT(JDBCJobStore的子类),Quartz 能参与JTA事务;Quartz 能管理JTA事务(开始和提交)在执行任务之间,这样,任务做的事就可以发生在JTA事务里。 Task 默认单线程同步执行 单个任务时,当前次的调度完成后,再执行下一次任务调度 多个任务时,一个任务执行完成后才会执行下一个任务。若需要任务能够并发执行,需手动设置线程池 触发方式: 与Quartz的CronTrigger的表达式类似 可以使用注解标注定时任务 比较: 实现,Task注解实现方式,比较简单。Quartz需要手动配置Jobs。 任务执行,Task默认单线程串行执行任务,多任务时若某个任务执行时间过长,后续任务会无法及时执行。Quartz采用多线程,无这个问题。 调度,Task采用顺序执行,若当前调度占用时间过长,下一个调度无法及时执行; Quartz采用异步,下一个调度时间到达时,会另一个线程执行调度,不会发生阻塞问题,但调度过多时可能导致数据处理异常