今天在项目中需要有一个及时的任务调度方法,但是该方法的使用频率不会太高。
在项目的原有基础上已经使用了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();
}
}
}