java 多线程 目录:
概述
第1部分 配置
有关quartz的api文档地址:Quartz Enterprise Job Scheduler 1.8.6 API
主要接口目录:
重点看下Job,Scheduler,Trigger,JobDetail几个:
代表任务的类继承Job接口,该接口只有唯一一个方法 execute;当一个任务的触发器启动时,相应的调度器scheduler会调用该任务。
quartz并不保存一个实际的Job类,而是通过允许你定义一个JobDetail取代。
Scheduler代表JobDetails和Triggers的登记表,Scheduler由SchedulerFactory产生。
quartz的配置文件quartzConfig.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.1.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <!-- ====================================================================================== -->
<!-- 拦截器配置文件 -->
<!-- ====================================================================================== -->
<!-- <bean id="startQuartz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> </bean> -->
<!-- ====================================================================================== --> <!-- 要调用的工作类 -->
<bean id="quartzJob" class="com.util.CallQuartz"></bean>
<!-- 定义调用对象和调用对象的方法 -->
<bean id="jobtask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 调用的类 -->
<property name="targetObject">
<ref bean="quartzJob"/>
</property>
<!-- 调用类中的方法 -->
<property name="targetMethod">
<value>callAllQuartz</value>
</property>
</bean>
<!-- 定义触发时间 -->
<bean id="doTime" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="jobtask"/>
</property>
<!-- cron表达式 -->
<property name="cronExpression">
<value>*/10 * * * * ?</value>
</property>
</bean>
<!-- 总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序 -->
<bean id="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="doTime"/>
</list>
</property>
</bean> <!-- ====================================================================================== -->
</beans>
web.xml文件中加入相应上述加载配置文件路径。
第2部分 代码示例
首先定义一个任务的类
package com.util.vo; import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException; /**
*
* @ClassName: QuartzVo
*
* @author Xingle
* @date 2014-8-14 下午12:49:25
*/
public class QuartzVo implements Job{ public static int Id = 0; private static Logger logger = Logger.getLogger(QuartzVo.class);
//缓存中任务列表
public static List<QuartzVo> quartzList = new ArrayList<QuartzVo>();
//缓存中任务map
public static Map<String, QuartzVo> quartzMap = new HashMap<String, QuartzVo>(); /**
* id
*/
public String id ;
/**
* 任务名称
*/
public String jobTitle;
/**
* 调度路径
*/
public String jcallpath;
/**
* 触发表达式
*/
public String jobcron;
/**
* @Fields s_date : 开始时间
*/
public String s_date;
/**
* @Fields cycle : 循环标示:1 循环;2 单次
*/
public String cycle; public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getJobTitle() {
return jobTitle;
}
public void setJobTitle(String jobTitle) {
this.jobTitle = jobTitle;
}
public String getJcallpath() {
return jcallpath;
}
public void setJcallpath(String jcallpath) {
this.jcallpath = jcallpath;
}
public String getJobcron() {
return jobcron;
}
public void setJobcron(String jobcron) {
this.jobcron = jobcron;
}
public String getCycle() {
return cycle;
}
public void setCycle(String cycle) {
this.cycle = cycle;
} public String getS_date() {
return s_date;
}
public void setS_date(String s_date) {
this.s_date = s_date;
}
/**
* 执行任务
* @Description:
* @param arg0
* @throws JobExecutionException
* @author xingle
* @data 2014-8-14 下午12:51:35
*/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
String jobName = context.getJobDetail().getName();
logger.debug("定时任务【" + jobName + "】 将要执行 start!!");
QuartzVo quartzVo = QuartzVo.quartzMap.get(jobName);
String inurl = quartzVo.getJcallpath();
URL url = null;
HttpURLConnection conn = null;
try {
url = new URL(inurl);
conn = (HttpURLConnection) url.openConnection();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("***************** 连接失败,程序地址 : " + inurl);
e.printStackTrace();
}
try {
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
System.out.println("****************** 调度失败!!,程序地址 : " + inurl);
} else {
System.out.println("定时任务【" + jobName + "】" + "已完成调度,程序地址: "
+ inurl);
}
} catch (IOException e) {
e.printStackTrace();
} } }
定义一个调用任务:
package com.util; import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import com.util.vo.QuartzVo;
import com.whalin.MemCached.MemCachedClient; /**
* 调用任务
* @ClassName: CallQuartz
* TODO
* @author Xingle
* @date 2014-8-14 下午12:48:44
*/
public class CallQuartz {
private static Logger logger = Logger.getLogger(CallQuartz.class); @Autowired
@Qualifier("memcachedClient")
private MemCachedClient memClient; public void callAllQuartz(){
List<QuartzVo> list =new ArrayList<QuartzVo>();
Iterator<String> idIter = QuartzVo.quartzMap.keySet().iterator();
String idStr = "";
while(idIter.hasNext()){
idStr = idStr+idIter.next()+",";
}
logger.info("当前任务有: "+idStr);
String flag = "";
Map<String,List<QuartzVo> > map = this.getNewJobs();
Iterator<Entry<String, List<QuartzVo>>> iter = map.entrySet().iterator();
while(iter.hasNext()){
Entry<String, List<QuartzVo>> entry = iter.next();
flag = entry.getKey();
list = entry.getValue();
}
//新增
if("1".equals(flag)){
logger.info("新增加定时任务的数量:【 "+list.size()+"】");
for(int i =0;i<list.size();i++){
QuartzVo vo = list.get(i);
QuartzVo.quartzMap.put(vo.getJobTitle(), vo);
QuartzManager.addJob(vo.getJobTitle(), vo, vo.getJobcron()); }
}
else if("2".equals(flag)){
logger.info("删除的定时任务的数量:【 "+list.size()+"】");
for(int i =0;i<list.size();i++){
QuartzVo vo = list.get(i);
QuartzManager.removeJob(vo.getJobTitle());
QuartzVo.quartzMap.remove(vo.getJobTitle());
} } } /**
* 获取任务
* @return
* @author xingle
* @data 2014-8-14 下午12:59:58
*/
private Map<String, List<QuartzVo>> getNewJobs() {
//返回的map
Map<String,List<QuartzVo>> returnMap=new HashMap<String,List<QuartzVo>>();
List<QuartzVo> returnLs = new ArrayList<>();
//文件列表
List<QuartzVo> fileLs = new ArrayList<>();
List<String> fileNameLs = new ArrayList<>();
BufferedReader ins = null;
File f = new File("D:\\test/tasklist1.txt");
try { int i = QuartzVo.Id++;
ins = new BufferedReader(new FileReader(f));
String line = "";
while ((line = ins.readLine()) != null) {
//增加一个是否执行标识,0 未执行
//line = line+"|0";
String[] task = line.split("\\|"); QuartzVo quartzVo = new QuartzVo();
String id = "quarzJob_"+ i;
quartzVo.setId(id);
quartzVo.setJobTitle(task[0]);
quartzVo.setJcallpath(task[1]);
quartzVo.setJobcron(task[2]);
quartzVo.setS_date(task[3]);
quartzVo.setCycle(task[4]); fileLs.add(quartzVo);
fileNameLs.add(quartzVo.getJobTitle());
}
ins.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} String flag = "";
int fileNum = fileLs.size();
int quarzNum = QuartzVo.quartzMap.size();
if(fileNum > quarzNum){
flag = "1";
for(int i =0;i<fileNum;i++){
QuartzVo fileVo = fileLs.get(i);
if(!QuartzVo.quartzMap.keySet().contains(fileVo.getJobTitle())){
QuartzVo.quartzList.add(fileVo);
//要增加的
returnLs.add(fileVo);
}
}
}
else if(fileNum<quarzNum){
flag = "2";
for(int i = 0;i<QuartzVo.quartzList.size() ; i++){
if(!fileNameLs.contains(QuartzVo.quartzList.get(i).getJobTitle())){
//需要要删除的任务
returnLs.add(QuartzVo.quartzList.get(i));
}
}
for(int i = 0;i<QuartzVo.quartzList.size() ; i++){
QuartzVo vo = QuartzVo.quartzList.get(i);
for(int j = 0;j<returnLs.size();j++){
if(vo.getId().equals(returnLs.get(j).getId())){
QuartzVo.quartzList.remove(i);
}
}
}
} returnMap.put(flag, returnLs);
return returnMap;
} }
任务管理:
package com.util; import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; import org.apache.log4j.Logger;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory; import com.util.vo.QuartzVo; /**
* 任务管理
* @ClassName: QuartzManager
*
* @author Xingle
* @date 2014-8-14 下午2:34:16
*/
public class QuartzManager {
private static Logger logger = Logger.getLogger(QuartzManager.class); //Create an uninitialized StdSchedulerFactory.
private static SchedulerFactory sf = new StdSchedulerFactory(); private static String TRIGGER_GROUP_NAME = "quartzTrigger"; /**
* 添加任务
* @param jobName
* @param job
* @param time
* @author xingle
* @data 2014-8-14 下午7:45:09
*/
public static void addJob(String jobName,QuartzVo job,String time){
try {
Scheduler scheduler = sf.getScheduler(); //任务名,任务组,任务执行类
JobDetail jobDetail = new JobDetail(jobName, jobName, job.getClass()); if("1".equals(job.getCycle())){//循环
CronTrigger trigger = new CronTrigger(jobName, jobName);
trigger.setCronExpression(time);
scheduler.scheduleJob(jobDetail, trigger);
}
else{//单次
String s_Date = job.getS_date();
logger.debug("*****时间:"+s_Date); SimpleDateFormat formate= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date startTime = formate.parse(s_Date);
logger.debug("*****时间:"+startTime);
SimpleTrigger trigger = new SimpleTrigger(jobName, jobName, startTime);
scheduler.scheduleJob(jobDetail, trigger);
}
if(!scheduler.isShutdown()){
scheduler.start();
}
logger.debug("*********【添加】定时任务【"+jobName+"】 加载完成!*****************"); } catch (SchedulerException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
} /**
* 删除任务
* @param jobName
* @author xingle
* @data 2014-8-14 下午7:45:16
*/
public static void removeJob(String jobName){
try {
Scheduler sched = sf.getScheduler();
sched.pauseTrigger(jobName,jobName);//停止触发器
sched.unscheduleJob(jobName,jobName);//移除触发器
sched.deleteJob(jobName, jobName);
} catch (SchedulerException e) {
e.printStackTrace();
}
logger.debug("*********定时任务【"+jobName+"】 已删除完成!*****************");
} }
读取的任务简单为下:
任务1|http://www.baidu.com|0 0/1 * * * ?||1
任务4|http://www.iteye.com/problems/99952||2014-08-15 11:34:15|2
任务5|https://pomotodo.com/app/|0 0/1 * * * ?||1
任务3|http://www.w3school.com.cn/html5/|0 0/1 * * * ?||1
任务6|http://tool.oschina.net/apidocs/apidoc?api=jdk-zh|0 0/2 * * * ?||1
其中Cron 触发器的时间设置可以参考有关内容配置,
以上任务可名称不可以重复,任务可随时添加和删除。
执行结果(截取):
中途删除任务3