QuartzManager
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 定時任務管理器
* 出現異常也不會掛掉,如果想結束,請調用remove方法移除任務
* @Description:
* @author: lhy
* @date: 2019年8月13日 下午11:31:20
*
*/
public class QuartzManager {
private final static Logger logger = LoggerFactory.getLogger(QuartzManager.class);
private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();
private static String JOB_GROUP_NAME = "MY_JOBGROUP_NAME";
private static String TRIGGER_GROUP_NAME = "MY_TRIGGERGROUP_NAME";
/**
* 只執行一次job
* @Description:
* @Creator: lhy
* @CreateTime: 2019年8月13日 下午8:00:57
* @Modifier:
* @ModifyTime:
* @Reasons:
* @param jobClass
* @param jobName
* @param jobGroupName
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static boolean runOnce(Class jobClass,String jobName,Map<String,Object> map){
boolean flag=true;
try {
Scheduler scheduler = gSchedulerFactory.getScheduler();
SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
.withIdentity(jobName, TRIGGER_GROUP_NAME)
.startAt(new Date())
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(3)
.withRepeatCount(0))//重複執行的次數,因爲加入任務的時候馬上執行了,所以不需要重複,否則會多一次。
.build();
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, JOB_GROUP_NAME).build();
jobDetail.getJobDataMap().putAll(map);
scheduler.scheduleJob(jobDetail, simpleTrigger);
// 啓動
if (!scheduler.isShutdown()) {
scheduler.start();
logger.info("添加任務:"+jobName);
}
} catch (Exception e) {
e.printStackTrace();
flag=false;
}
return flag;
}
/**
* @Description: 添加一個定時任務,使用默認的任務組名,觸發器名,觸發器組名
* @param jobName
* 任務名
* @param cls
* 任務
* @param time
* 時間設置,參考quartz說明文檔
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void addJob(String jobName, Class cls, String cron, Map<String,Object> map) {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
JobDetail job = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build();
job.getJobDataMap().putAll(map);
// 表達式調度構建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
// 按新的cronExpression表達式構建一個新的trigger
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, TRIGGER_GROUP_NAME)
.withSchedule(scheduleBuilder).build();
// 交給scheduler去調度
sched.scheduleJob(job, trigger);
// 啓動
if (!sched.isShutdown()) {
sched.start();
logger.info("添加任務:"+jobName);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 添加一個定時任務,並立即執行
* @param jobName
* 任務名
* @param jobGroupName
* 任務組名
* @param triggerName
* 觸發器名
* @param triggerGroupName
* 觸發器組名
* @param jobClass
* 任務
* @param time
* 時間設置,參考quartz說明文檔
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName,
Class jobClass, String cron) {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
JobDetail job = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
// 表達式調度構建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
// 按新的cronExpression表達式構建一個新的trigger
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName)
.withSchedule(scheduleBuilder).build();
sched.scheduleJob(job, trigger);
// 啓動
if (!sched.isShutdown()) {
sched.start();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 修改一個任務的觸發時間(使用默認的任務組名,觸發器名,觸發器組名)
* @param jobName
* @param time
*/
public static void modifyJobTime(String jobName, String cron) {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);
try {
Scheduler sched = gSchedulerFactory.getScheduler();
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
if (trigger == null) {
return;
}
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(cron)) {
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
// 按新的cronExpression表達式重新構建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新設置job執行
sched.rescheduleJob(triggerKey, trigger);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:修改任務,(可以修改任務名,任務類,觸發時間)
* 原理:移除原來的任務,添加新的任務
* @param oldJobName :原任務名
* @param jobName
* @param jobclass
* @param cron
* @date 2018年5月23日 上午9:13:10
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void modifyJob(String oldJobName, String jobName, Class jobclass, String cron) {
/*
* removeJob(oldJobName);
* addJob(jobName, jobclass, cron);
* logger.info("修改任務"+oldJobName);
*/
TriggerKey triggerKey = TriggerKey.triggerKey(oldJobName, TRIGGER_GROUP_NAME);
JobKey jobKey = JobKey.jobKey(oldJobName, JOB_GROUP_NAME);
try {
Scheduler sched = gSchedulerFactory.getScheduler();
Trigger trigger = (Trigger) sched.getTrigger(triggerKey);
if (trigger == null) {
return;
}
sched.pauseTrigger(triggerKey);// 停止觸發器
sched.unscheduleJob(triggerKey);// 移除觸發器
sched.deleteJob(jobKey);// 刪除任務
logger.info("移除任務:" + oldJobName);
JobDetail job = JobBuilder.newJob(jobclass).withIdentity(jobName, JOB_GROUP_NAME).build();
// 表達式調度構建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
// 按新的cronExpression表達式構建一個新的trigger
Trigger newTrigger = TriggerBuilder.newTrigger().withIdentity(jobName, TRIGGER_GROUP_NAME)
.withSchedule(scheduleBuilder).build();
// 交給scheduler去調度
sched.scheduleJob(job, newTrigger);
// 啓動
if (!sched.isShutdown()) {
sched.start();
logger.info("添加新任務:" + jobName);
}
logger.info("修改任務【" + oldJobName + "】爲:" + jobName);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 修改一個任務的觸發時間
* @param triggerName
* @param triggerGroupName
* @param time
*/
public static void modifyJobTime(String triggerName, String triggerGroupName, String cron) {
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
try {
Scheduler sched = gSchedulerFactory.getScheduler();
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
if (trigger == null) {
return;
}
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(cron)) {
// trigger已存在,則更新相應的定時設置
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
// 按新的cronExpression表達式重新構建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新設置job執行
sched.resumeTrigger(triggerKey);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description 移除一個任務(使用默認的任務組名,觸發器名,觸發器組名)
* @param jobName
*/
public static void removeJob(String jobName) {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);
JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);
try {
Scheduler sched = gSchedulerFactory.getScheduler();
Trigger trigger = (Trigger) sched.getTrigger(triggerKey);
if (trigger == null) {
return;
}
sched.pauseTrigger(triggerKey);// 停止觸發器
sched.unscheduleJob(triggerKey);// 移除觸發器
sched.deleteJob(jobKey);// 刪除任務
logger.info("移除任務:"+jobName);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 移除一個任務
* @param jobName
* @param jobGroupName
* @param triggerName
* @param triggerGroupName
*/
public static void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, triggerGroupName);
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
try {
Scheduler sched = gSchedulerFactory.getScheduler();
sched.pauseTrigger(triggerKey);// 停止觸發器
sched.unscheduleJob(triggerKey);// 移除觸發器
sched.deleteJob(jobKey);// 刪除任務
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:暫停一個任務(使用默認組名)
* @param jobName
*/
public static void pauseJob(String jobName) {
JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);
try {
Scheduler sched = gSchedulerFactory.getScheduler();
sched.pauseJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* @Description:暫停一個任務
* @param jobName
* @param jobGroupName
*/
public static void pauseJob(String jobName, String jobGroupName) {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
try {
Scheduler sched = gSchedulerFactory.getScheduler();
sched.pauseJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* @Description:恢復一個任務(使用默認組名)
* @param jobName
*/
public static void resumeJob(String jobName) {
JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);
try {
Scheduler sched = gSchedulerFactory.getScheduler();
sched.resumeJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* @Description:恢復一個任務
* @param jobName
* @param jobGroupName
* @date 2018年5月17日 上午9:56:09
*/
public static void resumeJob(String jobName, String jobGroupName) {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
try {
Scheduler sched = gSchedulerFactory.getScheduler();
sched.resumeJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* @Description:啓動所有定時任務
*/
public static void startJobs() {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
sched.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description 關閉所有定時任務
*/
public static void shutdownJobs() {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
if (!sched.isShutdown()) {
sched.shutdown();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 立即運行任務,這裏的立即運行,只會運行一次,方便測試時用。
* @param jobName
* @param jobGroupName
* @date 2018年5月17日 上午10:03:26
*/
public static void triggerJob(String jobName) {
JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);
try {
Scheduler sched = gSchedulerFactory.getScheduler();
sched.triggerJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* @Description: 立即運行任務,這裏的立即運行,只會運行一次,方便測試時用。
* @param jobName
* @param jobGroupName
* @date 2018年5月17日 上午10:03:26
*/
public static void triggerJob(String jobName, String jobGroupName) {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
try {
Scheduler sched = gSchedulerFactory.getScheduler();
sched.triggerJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* @Description: 獲取任務狀態
* NONE: 不存在
* NORMAL: 正常
* PAUSED: 暫停
* COMPLETE:完成
* ERROR : 錯誤
* BLOCKED : 阻塞
* @param jobName 觸發器名
* @date 2018年5月21日 下午2:13:45
*/
public static String getTriggerState(String jobName){
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);
String name = null;
try {
Scheduler sched = gSchedulerFactory.getScheduler();
TriggerState triggerState = sched.getTriggerState(triggerKey);
name = triggerState.name();
} catch (SchedulerException e) {
e.printStackTrace();
}
return name;
}
/**
* @Description:獲取最近8次執行時間
* @param cron
* @date 2018年5月24日 下午5:13:03
*/
public static List<String> getRecentTriggerTime(String cron) {
List<String> list = new ArrayList<String>();
try {
CronTriggerImpl cronTriggerImpl = new CronTriggerImpl();
cronTriggerImpl.setCronExpression(cron);
// 這個是重點,一行代碼搞定
List<Date> dates = TriggerUtils.computeFireTimes(cronTriggerImpl, null, 8);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (Date date : dates) {
list.add(dateFormat.format(date));
}
} catch (ParseException e) {
e.printStackTrace();
}
return list;
}
}
TestJob--Job類
import java.text.SimpleDateFormat;
import java.util.Calendar;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestJob implements Job{
private final static Logger logger = LoggerFactory.getLogger(TestJob.class);
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
logger.info("################任務運行開始-------- start --------");
String jobName = context.getJobDetail().getKey().getName();
String jobGroup = context.getJobDetail().getKey().getGroup();
String triggerName = context.getTrigger().getKey().getName();
String triggerGroup = context.getTrigger().getKey().getGroup();
try {
JobDataMap map = context.getJobDetail().getJobDataMap();
logger.info("################"+map.getString("id")+"_"+jobName);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH時mm分ss秒");
logger.info("觸發器Key:" + triggerName + ".." + triggerGroup + " 正在執行...");
logger.info("任務Key:" + jobName + ".." + jobGroup + " 正在執行,執行時間: "
+ dateFormat.format(Calendar.getInstance().getTime()));
} catch (Exception e) {
QuartzManager.removeJob(jobName);
e.printStackTrace();
}
}
}
Test1--執行 main方法
import java.util.HashMap;
import java.util.Map;
public class Test1 {
public static void main(String[] args) throws InterruptedException {
Map<String,Object>m=new HashMap<>();
m.put("id", "45678");
//Boolean b=QuartzManager.runOnce(TestJob.class, "12345", m);
//System.out.println(b);
//addJob 同時立即執行
System.out.println("&&&&&&&&&&&&&&&&&&&&&&:addJob1");
QuartzManager.addJob("acbdad", TestJob.class, "0/8 * * * * ? ", m);
// Thread.sleep(10000);
// System.out.println("&&&&&&&&&&&&&&&&&&&&&&:triggerJobq");
// QuartzManager.triggerJob("acbdad");//立即執行一次
// Thread.sleep(10000);
// System.out.println("&&&&&&&&&&&&&&&&&&&&&&:modifyJobTime1");
// QuartzManager.modifyJobTime("acbdad", "0/2 * * * * ? ");//運行時修改可立即(執行完這次)生效
// Thread.sleep(10000);
System.out.println("&&&&&&&&&&&&&&&&&&&&&&:pauseJob");
QuartzManager.pauseJob("acbdad");//暫停,
Thread.sleep(10000);
System.out.println("&&&&&&&&&&&&&&&&&&&&&&:modifyJobTime2");
QuartzManager.modifyJobTime("acbdad", "0/4 * * * * ? ");//暫停的時候修改,會立即恢復執行修改後的cron,並且會一次性執行暫停時堆積的任務
// Thread.sleep(10000);
// System.out.println("&&&&&&&&&&&&&&&&&&&&&&:resumeJob1");
// QuartzManager.resumeJob("acbdad");//暫停後, 到下次resumeJob會一次性執行暫停時堆積的任務。
// Thread.sleep(10000);
// System.out.println("&&&&&&&&&&&&&&&&&&&&&&:removeJob");
// QuartzManager.removeJob("acbdad");//移除
//
// System.out.println("&&&&&&&&&&&&&&&&&&&&&&:resumeJob2");
// QuartzManager.resumeJob("acbdad");//removejob後resumeJob不起作用
// Thread.sleep(10000);
// System.out.println("&&&&&&&&&&&&&&&&&&&&&&:triggerJob2");
// QuartzManager.triggerJob("acbdad");//removejob後triggerJob不起作用,會拋出異常
// Thread.sleep(10000);
// System.out.println("&&&&&&&&&&&&&&&&&&&&&&:addJob2");
// QuartzManager.addJob("acbdad", TestJob.class, "0/5 * * * * ? ", m);//remove後必須再次addJob才能起作用
QuartzManager.shutdownJobs();//關閉芳芳是關閉整個調度器對象(包括所有的調度任務),此時無法獲得調度器狀態
QuartzManager.startJobs();//關閉後的調度器,必須start纔可正常使用
/*Thread.sleep(10000);
System.out.println("*****************end");*/
}
}