今天在项目中需要有一个及时的任务调度方法,但是该方法的使用频率不会太高。
在项目的原有基础上已经使用了quartz框架,就不再考虑线程方法。但是由于原来都是通过配置文件 和 cron表达式来完成的,所以显然无法完成我的触发器动作了。因此需要去手动的调用 重启 关闭等动作。
从网上找了很多资料,大体上没有什么问题,但一般都是通过 Thread.sleep(600L * 1000L); 这样的方法来控制程序进行后停止,清除内存的。
参考资料:http://zhaohaolin.iteye.com/blog/1187305
我觉得这样的操作是很不靠谱的,毕竟我们不能确定程序的执行时间到底是多少,太短的话 程序肯定执行不完,太长的话明显不合适 从网上又没有找不到什么解决办法,只能自己来实现了一个简单的状态判断
首先要知道quartz都有哪些状态信息: sched.getTriggerState(trigger.getKey())
BLOCKED 4
COMPLETE 2
ERROR 3
NONE -1
NORMAL 0
PAUSED 1
通过名称很明显的看出程序的运行状态,在这里 我用到的主要是 normal 和 none,一个代表运行正常 一个代表运行完成,ok
这样我就可以通过isOver方法循环判断程序是否运行完成了,完成后关闭。
import static org.quartz.JobBuilder.newJob; import static org.quartz.TriggerBuilder.newTrigger; import java.text.SimpleDateFormat; import java.util.Date; import org.quartz.DateBuilder; import org.quartz.Job; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.SchedulerMetaData; import org.quartz.SimpleTrigger; import org.quartz.Trigger; import org.quartz.Trigger.TriggerState; import org.quartz.impl.StdSchedulerFactory; public class InspectInfoJob implements Job { public void execute(JobExecutionContext arg0) throws JobExecutionException { System.out.println("<------------------------->start"); for(int i=0;i <100000;i++ ) { System.out.println("<---------->"+i); } System.out.println("<------------------------->end"); } public void run() throws Exception { // 日期格式化 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SchedulerFactory sf = new StdSchedulerFactory(); Scheduler sched = sf.getScheduler(); System.out.println("--------------- 初始化 -------------------"); Date startTime = DateBuilder.nextGivenSecondDate(null, 15); // job1 将只会执行一次 JobDetail job = newJob(InspectInfoJob.class).withIdentity("inspectInfoJob", "group").build(); SimpleTrigger trigger = (SimpleTrigger) newTrigger() .withIdentity("inspectInfoJobTrigger", "group") .startAt(startTime).build(); // 把job1 和 trigger加入计划 . ft:此任务要执行的时间 Date ft = sched.scheduleJob(job, trigger); System.out.println(job.getKey().getName() + " 将在 : " + dateFormat.format(ft) + " 时运行.并且重复: " + trigger.getRepeatCount() + " 次, 每次间隔 " + trigger.getRepeatInterval() / 1000 + " 秒"); sched.start(); System.out.println(sched.getTriggerState(trigger.getKey())); try { System.out.println("------- 等待1分钟 ... ------------"); Thread.sleep(60L*100L); } catch (Exception e) { } if(isOver(sched, trigger)) { sched.shutdown(true); } System.out.println("------- 调度已关闭 ---------------------"); // 显示一下 已经执行的任务信息 SchedulerMetaData metaData = sched.getMetaData(); System.out.println("~~~~~~~~~~ 执行了 " + metaData.getNumberOfJobsExecuted() + " 个 jobs."); } public boolean isOver(Scheduler sched,Trigger trigger) { TriggerState state = null; try { state = sched.getTriggerState(trigger.getKey()); } catch (SchedulerException e2) { e2.printStackTrace(); } String stateName = state.name(); System.out.println("------- 判断任务是否完成 ---------------------"+stateName); if(stateName.equals("NONE")) { System.out.println("------- 任务已完成 ---------------------"); return true; } else { try { System.out.println("------- 任务未完成等待一分钟 ---------------------"); Thread.sleep(60L*1000L); return isOver(sched,trigger); } catch (InterruptedException e) { e.printStackTrace(); } } return false; } public static void main(String[] args) { InspectInfoJob inspectInfoJob = new InspectInfoJob(); try { inspectInfoJob.run(); } catch (Exception e) { e.printStackTrace(); } } }