java中基于线程池和反射机制实现定时任务

标签: java 线程池 反射 | 发表时间:2013-09-03 05:54 | 作者:5iasp
出处:http://blog.csdn.net

直接上代码:

 

主要包括如下实现类:

1. Main类:


任务执行的入口:

调用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(1); 
		/*
		TaskModel tm=new TaskModel();
		tm.setClassName("com.yanek.task.TaskA");
		tm.setMethodName("testA");
		tm.setInitialDelay(3);
		tm.setPeriod(5);
		*/
		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 类 实现Runnable接口,在main类中调用

 

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. 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;

	}

}


5. 配置文件:

 

<?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>

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

</taskconfig>


5. 测试任务类:

 

TaskA TaskB TaskC其中定义静态方法 ,这些类的静态方法配置在 xml文件中,被调用。

 

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

}


 

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

}


 

 

 

 

 

作者:5iasp 发表于2013-9-2 21:54:19 原文链接
阅读:0 评论:0 查看评论

相关 [java 线程池 反射] 推荐:

Java线程池

- - 企业架构 - ITeye博客
线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的. 在jdk1.5之后这一情况有了很大的改观. Jdk1.5之后加入了java.util.concurrent包,这个包中主要介绍java中线程以及线程池的使用. 为我们在开发中处理线程的问题提供了非常大的帮助.

Java 线程池

- - 编程语言 - ITeye博客
在项目中,系统启动一个新线程的成本是比较高的,因为它涉及与操作系统交互. 在这种情形下,使用线程池可以很好地提高性能,尤其是当程序中需要创建大量生存周期很短的线程时,更应该考虑使用线程池. 使用线程池可以有效地控制系统中并发线程的数量,当系统中包含大量并发线程时,会导致系统性能剧烈下降,甚至导致JVM崩溃,而线程池的最大线程数参数可以控制系统中并发线程数不超过此数.

java中基于线程池和反射机制实现定时任务

- - CSDN博客推荐文章
调用main方法,开始加载任务配置并执行任务. MyTask 类 实现Runnable接口,在main类中调用. TaskModel: 对任务类的封装. XmlReader 任务配置解析类. System.out.println("距离首次运行还差" + initialDelay + "秒. TaskA TaskB TaskC其中定义静态方法 ,这些类的静态方法配置在 xml文件中,被调用.

java线程池分析

- - BlogJava-首页技术区
    在Java 5.0之前启动一个任务是通过调用Thread类的start()方法来实现的,任务的提于交和执行是同时进行的,如果你想对任务的执行进行调度或是控制 同时执行的线程数量就需要额外编写代码来完成. 5.0里提供了一个新的任务执行架构使你可以轻松地调度和控制任务的执行,并且可以建立一个类似数据库连接 池的线程池来执行任务.

Java线程池应用

- - CSDN博客架构设计推荐文章
1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务. 2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机). Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具.

Java线程池总结

- - Java - 编程语言 - ITeye博客
  假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间. 当T1 + T3 远大于 T2时,采用多线程技术可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     线程池就是一个线程的容器,每次只执行额定数量的线程, 线程池作用就是限制系统中执行线程的数量.

java 线程池原理及几种线程池详解

- - CSDN博客综合推荐文章
服务器经常出现处理大量单个任务处理的时间很短而请求的数目却是巨大的请求. 构建服务器应用程序的一个过于简单的模型应该是:每当一个请求到达就创建一个新线程,然后在新线程中为请求服务. 实际上,对于原型开发这种方法工作得很好,但如果试图部署以这种方式运行的服务器应用程序,那么这种方法的严重不足就很明显.

Java四种线程池的使用

- - ITeye博客
Java通过Executors提供四种线程池,分别为:. newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程. newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待. newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行.

java 线程池使用 Runnable&Callable&Future

- - Java - 编程语言 - ITeye博客
执行一次线程,调用Runnable接口实现.  当线程池执行Runnable后,返回的Future.get()总是null. DefaultRunnable代码如下:. 执行一次线程,调用Callable接口实现.  当线程池执行Callable时,返回的Future.get() 会返回Callable的返回值.

Java 线程池的原理与实现

- - CSDN博客编程语言推荐文章
这几天主要是狂看源程序,在弥补了一些以前知识空白的同时,也学会了不少新的知识(比如 NIO),或者称为新技术吧. 线程池就是其中之一,一提到线程,我们会想到以前《操作系统》的生产者与消费者,信号量,同步控制等等. 一提到池,我们会想到数据库连接池,但是线程池又如何呢. 建议:在阅读本文前,先理一理同步的知识,特别是syncronized同步关键字的用法.