定时任务与基本概念
在指定的时间,做指定的动作
简单启动一个调度器
public class QuartzTest {
public static void main(String[] args) {
try {
//从调度器工程获得一个调度器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动
scheduler.start();
scheduler.shutdown();
} catch (SchedulerException se) {
se.printStackTrace();
}
}
}
示例代码,获取scheduler实例对象,启动,然后关闭。
当调用StdSchedulerFactory.getDefaultScheduler()获取scheduler实例对象后,在调用scheduler.shutdown()之前,scheduler不会终止,因为还有活跃的线程在执行。
日期格式类,用于转变格式
import java.text.SimpleDateFormat;
import java.util.Date;
public class DFUtil {
public static final SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static String format(Date date){
return sdf.format(date);
}
}
新建一个HelloJob类
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("HelloJob.execute"+ DFUtil.format(new Date())+' '+Thread.currentThread().getName());
}
}
测试实例
在调用shutdown()之前,需要给job的触发和执行预留一些时间,比如,你可以调用Thread.sleep(60000)让线程睡眠一段时间。
定义一个JobDetail和一个Trigger容器,5秒执行一次,永远执行
public static void main(String[] args) {
try {
//从调度器工程获得一个调度器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动
scheduler.start();
// 定义一个作业详情
JobDetail job= JobBuilder.newJob(HelloJob.class)
.withIdentity("job1", "group1")
.build();
//触发器定义调度策略
Trigger trigger= TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(5)
.repeatForever())
.build();
// Tell quartz to schedule the job using our trigger
scheduler.scheduleJob(job, trigger);
TimeUnit.SECONDS.sleep(20);
scheduler.shutdown();
} catch (SchedulerException se) {
se.printStackTrace();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
执行结果
触发器
一个调度器调度多个触发器,一个触发器只能调度一个任务,一个任务可以被多个触发器调度。
两个触发器调用同一个作业
一般一个任务详情关联一个任务job
SimpleTrigger
实例代码
JobDetail job= JobBuilder.newJob(HelloJob.class)
.withIdentity("job1", "group1")
.build();
// Trigger the job to run now, and then repeat every 40 seconds
Trigger trigger= TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(1)
.repeatForever())
.build();
Trigger trigger2 = TriggerBuilder.newTrigger()
.withIdentity("trigger2", "group1")
.forJob("job1", "group1")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(3)
.repeatForever())
.build();
// Tell quartz to schedule the job using our trigger
scheduler.scheduleJob(job, trigger);
scheduler.scheduleJob(trigger2);
TimeUnit.SECONDS.sleep(3);
scheduler.shutdown();
触发器分为四种:
SimpleTrigger
CronTrigger
CalendarIntervalTrigger
DailyTimeIntervalTrigger
CronTrigger
CronTrigger可以满足工作中大部分需求。
一个完整的Cron-Expressions的例子是字符串“0 0 12?* WED“ - 这意味着”每个星期三下午12:00“。
| 秒 | 分 | 时 | 日 | 月 | 星期 | 年 | |
|---|---|---|---|---|---|---|---|
| 允许的符号 | , - * / | , - * / | , - * / | , - * / ?LW | , - * / | , - * / ?L# | , - * / |
| 允许的值 | 0-59 | 0-59 | 0-23 | 1-31 | 0-11 | 1-7 | 1970-2199 |
月是0-11,从1月到12月。
星期是1-7,1是星期天。
- ‘*‘ 代表所有值。例如,分钟字段中的’*‘代表’每分钟’。
- ‘?’ ‘日’和’星期’字段可以使用。代表不确定,例如每个月的15日,不确定是周几,可用’?’代替。’* * * 15 * ? *’
- ‘,’ 用于指定其他值,例如’星期几’字段中的’MON’,’WED’,’FRI’表示’星期一’、’星期三’、’星期五’。
- ‘/‘ 表示指定增量。例如’0/5 * * * * * *’表示每5s的第0s执行。(注意,不能超过上限,例如0/40,只能在第0s和第40s执行)
- ‘L’ 表示最后。例如每个月的最后一天。’* * * ? * L ‘表示每月的最后一天。在’星期几’使用表示’周六’如果在星期几加入数字,例如’0 0 0 ? 8 3L 2020’表示2020年9月第三个星期六。’L’还可以指定与最后一天的偏移量。例如’0 0 0 L-3 * ? 2020’表示2020年每月倒数第三天执行。*使用’L’选项时,不要制定列表或者值的范围,例如’1-3’和’L-3’中的’-‘冲突。
- ‘W’ 表示工作日(周一至周五)。指定’15W’表示’离月15日最近的工作日’。在日字段上写’LW’表示每个月最后一个工作日。
- ‘#’ 只能用在’星期几’里,例如’6#3’的值表示该月的第三个星期五。如果使用’#’字符,则’星期几’字段里只能有一个表达式。