1.创建一个定时任务
package com.test.quartz;
import org.quartz.*;
public class MyOneTimeJob implements Job {
@Override
public void execute(JobExecutionContext context) {
JobKey jobKey = context.getJobDetail().getKey();
String name = jobKey.getName();
String group = jobKey.getGroup();
TriggerKey triggerKey = TriggerKey.triggerKey(name, group);
Scheduler scheduler = context.getScheduler();
try {
// 在这里是卸载触发器以及定时任务,用于只执行一次的任务,用完就卸了
scheduler.pauseTrigger(triggerKey);
scheduler.unscheduleJob(triggerKey);
scheduler.deleteJob(jobKey);
} catch (SchedulerException e) {
throw new RuntimeException(e);
}
// 这里是你的任务逻辑
System.out.println("MyOneTimeJob is executing." + System.currentTimeMillis());
}
}
2.测试逻辑
package com.test.quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class QuartzOneTimeJobExample {
// 构建定时任务
public static JobDetail buildJobDetail(Class<? extends Job> tClass, String name, String group, Map<String, Object> map) {
return JobBuilder.newJob(tClass)
.withIdentity(name, group)
.storeDurably()
.setJobData(new JobDataMap(map))
.build();
}
// 构建触发器
public static Trigger jobTrigger(JobDetail jobDetail, long intervalTime) {
// 创建一个触发器(Trigger)实例,并为其设置名称、开始时间和重复规则
long startTime = System.currentTimeMillis() + intervalTime;
return TriggerBuilder.newTrigger()
.withIdentity(jobDetail.getKey().getName(), jobDetail.getKey().getGroup()) // 设置触发器的名称和组,不能为空
.startAt(new Date(startTime))
.build();
}
public static void main(String[] args) throws SchedulerException {
// 设置线程池线程数量为 1 ,方便调试
System.setProperty("org.quartz.threadPool.threadCount", "1");
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
JobDetail jobDetail = buildJobDetail(MyOneTimeJob.class, "MyOneTimeJob", "MyOneTimeJob", new HashMap<>());
Trigger trigger = jobTrigger(jobDetail, 1000);
System.out.println("开始时间" + System.currentTimeMillis());
scheduler.scheduleJob(jobDetail, trigger);
if (!scheduler.isStarted()) {
scheduler.start();
}
while (!scheduler.isShutdown()) {
List<String> jobGroupNames = scheduler.getJobGroupNames();
System.out.println(jobGroupNames.size());
for (String jobGroupName : jobGroupNames) {
System.out.println(jobGroupName);
}
if (jobGroupNames.size() == 0) {
scheduler.shutdown();
}
}
}
}
3. 定时器 等于 任务队列 + 轮循
任务投递位置
追到下方可以发现这里是用TreeSet 来维护的 队列
比较逻辑如下:
可以看出维护队列的条件有下一次执行时间,优先级,key 的大小顺序