首页 > 代码库 > 使用Java并发包线程池和XML实现定时任务动态配置和管理

使用Java并发包线程池和XML实现定时任务动态配置和管理

文章标题:使用并发包线程池和XML实现定时任务动态配置和管理

 

文章地址: http://blog.csdn.net/5iasp/article/details/32705601

作者: javaboy2012
Email:yanek@163.com
qq:    1046011462

 

 

项目结构:

 


一、采用的知识点:

1. java并发包
2. xml配置文件读取
3. 反射动态调用类的方法


二、 基本思路

 1.  创建线程池: ScheduledExecutorService scheduExec = Executors.newScheduledThreadPool(10);

 2.  系统启动读取配置文件加载需要执行的任务列表。

 

List tasks=XmlReader.getTasks();		for (int i=0;i<tasks.size();i++)		{			TaskModel tm=(TaskModel)tasks.get(i);			scheduExec.scheduleAtFixedRate(new MyTask(tm),tm.getInitialDelay(), tm.getPeriod(), TimeUnit.SECONDS); 		}



 

三 代码实现:


  主要包括如下几个类和配置文件:


 1. 启动类:  Main类

package com.yanek.task;import java.util.List;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;public class Main {	/**	 * @param args	 */	public static void main(String[] args) {				ScheduledExecutorService scheduExec = Executors.newScheduledThreadPool(10); 		List tasks=XmlReader.getTasks();		for (int i=0;i<tasks.size();i++)		{			TaskModel tm=(TaskModel)tasks.get(i);			scheduExec.scheduleAtFixedRate(new MyTask(tm),tm.getInitialDelay(), tm.getPeriod(), TimeUnit.SECONDS); 		}			}}


 2. MyTask类,实现Runable接口,线程池中调用

 

package com.yanek.task;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Date;public class MyTask implements Runnable {	private TaskModel taskModel;	public MyTask() {}		public MyTask(TaskModel tm) {		this.taskModel = tm;	}	  	public void run() {	     System.out.println("call at " + (new Date()));	     try {				Class<?> classType = Class.forName(taskModel.getClassName());				Method getMethod = classType.getMethod(taskModel.getMethodName());				getMethod.invoke(classType);					     } catch (SecurityException e) {				e.printStackTrace();		 } catch (IllegalArgumentException e) {				e.printStackTrace();		 } catch (ClassNotFoundException e) {				e.printStackTrace();		 } catch (NoSuchMethodException e) {				e.printStackTrace();		 } catch (IllegalAccessException e) {				e.printStackTrace();		 } catch (InvocationTargetException e) {				e.printStackTrace();		 }			}}


 

其中使用到反射机制。


3. TaskModel类:任务配置的封装类

 

package com.yanek.task;public class TaskModel {			public String getClassName() {		return className;	}	public void setClassName(String className) {		this.className = className;	}	public String getMethodName() {		return methodName;	}	public void setMethodName(String methodName) {		this.methodName = methodName;	}	public long getInitialDelay() {		return initialDelay;	}	public void setInitialDelay(long initialDelay) {		this.initialDelay = initialDelay;	}	public long getPeriod() {		return period;	}	public void setPeriod(long period) {		this.period = period;	}	private String className;	private String methodName;	private long initialDelay;	private long period;}


 

4. 任务配置文件: taskconfig.xml

例子如下:

<?xml version="1.0" encoding="UTF-8"?><taskconfig>    	<task>    			<class>com.yanek.task.TaskA</class>	    		<method>testA</method>	       		<initialDelay>5</initialDelay>	       		<period>2</period>    	</task>    	<task>    			<class>com.yanek.task.TaskB</class>	    		<method>testB</method>	       		<initialDelay>5</initialDelay>	       		<period>3</period>    	</task></taskconfig>


其中 一个元素<task>,对应一个类TaskModel的实例。配置包括需要线程池执行的类的名字,方法,和延迟执行的参数,重复执行的周期,

 

5. 具体需要执行的类:

 TaskA类
 TaskB类

package com.yanek.task;public class TaskA {	/**	 * @param args	 */	public static void main(String[] args) {			System.out.println("task a test");	}			public static void testA()	{				System.out.println("taska testA method call!");			}}package com.yanek.task;public class TaskB {	/**	 * @param args	 */	public static void main(String[] args) {			System.out.println("task b test");	}		public static void testB()	{				System.out.println("TaskB testB method call!");			}}


6. XmlReader: 配置文件读取工具类

 

package com.yanek.task;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.List;import org.apache.commons.lang.StringUtils;import org.jdom.Document;import org.jdom.Element;import org.jdom.JDOMException;import org.jdom.input.SAXBuilder;public class XmlReader {	public static void main(String[] args) {		XmlReader.getTasks();	}	public static List getTasks() {		List tasks = new ArrayList();				System.out.println("load task config start...");				String path = "/work/TaskManager/conf/taskconfig.xml";		File file = new File(path);		if (file.exists() && !file.isDirectory()) {			try {				SAXBuilder sx = new SAXBuilder();				Document doc = sx.build(file);				Element rootelement = doc.getRootElement();													List<Element> childs = rootelement.getChildren();					for (int i = 0; i < childs.size(); i++) {						TaskModel tModel = new TaskModel();						tModel.setClassName(childs.get(i).getChildText("class"));						System.out.println(childs.get(i).getChildText("class"));						tModel.setMethodName(childs.get(i).getChildText("method"));						System.out.println(childs.get(i).getChildText("method"));						String initialDelay = childs.get(i).getChildText("initialDelay");												tModel.setInitialDelay((Long.valueOf(initialDelay)));						System.out.println("距离首次运行还差" + initialDelay + "秒!");						tModel.setPeriod(Integer.valueOf(childs.get(i).getChildText("period")));						System.out.println(childs.get(i).getChildText("period"));						tasks.add(tModel);									}			} catch (NumberFormatException e) {				// TODO Auto-generated catch block				e.printStackTrace();			} catch (JDOMException e) {				// TODO Auto-generated catch block				e.printStackTrace();			} catch (IOException e) {				// TODO Auto-generated catch block				e.printStackTrace();			}		} else {			System.out.println("file no exist!");		}		System.out.println("load task config end !");		return tasks;	}}


 


四、测试执行:


执行Main类即可看到效果:

load task config start...
com.yanek.task.TaskA
testA
距离首次运行还差5秒!
2
com.yanek.task.TaskB
testB
距离首次运行还差5秒!
3
com.yanek.task.TaskC
testC
距离首次运行还差5秒!
3
load task config end !
call at Fri Jun 20 11:51:14 CST 2014
TaskB testB method call!
call at Fri Jun 20 11:51:14 CST 2014
call at Fri Jun 20 11:51:14 CST 2014
Taskc testC method call!
taska testA method call!
call at Fri Jun 20 11:51:16 CST 2014
taska testA method call!
call at Fri Jun 20 11:51:17 CST 2014
TaskB testB method call!
call at Fri Jun 20 11:51:17 CST 2014
Taskc testC method call!

五、使用方法:


   1. 编写需要执行的类和方法,注意方法为静态方法,无返回值。

       如下:

package com.yanek.task;public class TaskC {	/**	 * @param args	 */	public static void main(String[] args) {			System.out.println("task c test");	}		public static void testC()	{				System.out.println("Taskc testC method call! 具体的业务逻辑。");			}}


 


   2. 在配置文件中增加相应配置:

 

   <task>       <class>com.yanek.task.TaskC</class>       <method>testC</method>          <initialDelay>5</initialDelay>          <period>3</period>     </task>



 
   3. 启动Main类执行即可。

 

六、总结

 该文章主要介绍了相关的任务调度和实现机制和全部代码,本身可以封装为一个简单的任务调度框架,简单实用,写个简单类和方法,配置到配置文件里就可以了。

 希望对大家有所帮助,本文章为csdn 博客大赛参赛文章,也欢迎大家投票和多多点击,有问题欢迎大家指出,互相交流,共同进步。

 

学习是一种信仰,分享是一种美德