Quartz動態定時器

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");*/
	
}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章