java中基于TaskEngine类封装实现定时任务

主要包括如下几个类:

 

文章标题:java中基于TaskEngine类封装实现定时任务

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

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

 

 

 

1. 核心工具类: TaskEngine

 

package com.yanek.task;


import java.util.*;
import java.util.LinkedList;

import org.apache.log4j.Logger;



public class TaskEngine
{
	static Logger logger = Logger.getLogger(TaskEngine.class.getName());
    private static class PriorityQueue
    {

        public void enqueue(int priority, Object object)
        {
            if(priority > HIGH_PRIORITY)
                priority = HIGH_PRIORITY;
            else
            if(priority < LOW_PRIORITY)
                priority = LOW_PRIORITY;
            switch(priority)
            {
            case HIGH_PRIORITY: // '\002'
                high.addFirst(object);
                break;

            case MEDIUM_PRIORITY: // '\001'
                medium.addFirst(object);
                break;

            case LOW_PRIORITY: // '\0'
                low.addFirst(object);
                break;
            }
        }

        public boolean isEmpty()
        {
            return high.isEmpty() && medium.isEmpty() && low.isEmpty();
        }

        public int size()
        {
            return high.size() + medium.size() + low.size();
        }

        public Object dequeue()
        {
            Object object;
            if(!high.isEmpty())
                object = high.removeLast();
            else
            if(!medium.isEmpty())
                object = medium.removeLast();
            else
            if(!low.isEmpty())
                object = low.removeLast();
            else
                throw new NoSuchElementException("Queue is empty.");
            if(!low.isEmpty())
                medium.addFirst(low.removeLast());
            if(!medium.isEmpty())
                high.addFirst(medium.removeLast());
            return object;
        }

        private LinkedList high;
        private LinkedList medium;
        private LinkedList low;

        private PriorityQueue()
        {
            high = new LinkedList();
            medium = new LinkedList();
            low = new LinkedList();
        }

    }

    private static class ScheduledTask extends TimerTask
    {

        public void run()
        {
            TaskEngine.addTask(priority, task);
        }

        private int priority;
        private Runnable task;

        ScheduledTask(int priority, Runnable task)
        {
            this.priority = priority;
            this.task = task;
        }
    }

    private static class TaskEngineWorker extends Thread
    {

        public void stopWorker()
        {
            done = true;
        }

        public void run()
        {
            do
            {
                if(done)
                    break;
                int currentThreadPriority = getPriority();
                int newThreadPriority = currentThreadPriority;
                try
                {
                    TaskWrapper wrapper = TaskEngine.nextTask();
                    int desiredTaskPriority = wrapper.getPriority();
                    newThreadPriority = desiredTaskPriority != 2 ? ((int) (desiredTaskPriority != 1 ? 2 : 5)) : 9;
                    if(newThreadPriority != currentThreadPriority)
                        try
                        {
                            logger.debug("Running task engine worker (" + wrapper.getTask().getClass() + ") at thread priority " + newThreadPriority);
                            setPriority(newThreadPriority);
                        }
                        catch(Exception e)
                        {
                            logger.error(e);
                        }
                    logger.debug("Executing task (" + wrapper.getTask().getClass() + ")");
                    wrapper.getTask().run();
                    logger.debug("Completed execution task (" + wrapper.getTask().getClass() + ")");
                    if(newThreadPriority != currentThreadPriority)
                        try
                        {
                            logger.debug("Restoring task engine worker thread to thread priority - " + currentThreadPriority);
                            setPriority(currentThreadPriority);
                        }
                        catch(Exception e)
                        {
                            logger.error(e);
                        }
                }
                catch(Exception e)
                {
                    logger.error(e);
                    if(newThreadPriority != currentThreadPriority)
                        try
                        {
                            logger.debug("Restoring task engine worker thread to thread priority - " + currentThreadPriority);
                            setPriority(currentThreadPriority);
                        }
                        catch(Exception e2)
                        {
                            logger.error(e2);
                        }
                }
            } while(true);
        }

        private boolean done;

        TaskEngineWorker(String name)
        {
            super(TaskEngine.threadGroup, name);
            done = false;
        }
    }


    private TaskEngine()
    {
    }

    public static void start()
    {
        synchronized(lock)
        {
            started = true;
            lock.notifyAll();
        }
    }

    private static void initialize()
    {
        taskTimer = new Timer(true);
        taskQueue = new PriorityQueue();
        threadGroup = new ThreadGroup("Task Engine Workers");
        workers = new TaskEngineWorker[5];
        for(int i = 0; i < workers.length; i++)
        {
            workers[i] = new TaskEngineWorker("Task Engine Worker " + i);
            workers[i].setDaemon(true);
            workers[i].start();
        }

    }

    public static int size()
    {
    	synchronized(lock){
    		return taskQueue.size();
    	}

    }

    public static int getNumWorkers()
    {
        return workers.length;
    }

    public static void addTask(Runnable task)
    {
        addTask(1, task);
    }

    public static void addTask(int priority, Runnable task)
    {
        synchronized(lock)
        {
            if((double)taskQueue.size() > Math.ceil(workers.length / 2))
            {
                busyTimestamp = System.currentTimeMillis();
                addWorker();
            } else
            if(workers.length > 3)
                removeWorker();
            TaskWrapper wrapper = new TaskWrapper(priority, task);
            taskQueue.enqueue(priority, wrapper);
            lock.notify();
        }
    }

    public static TimerTask scheduleTask(Runnable task, Date date)
    {
        return scheduleTask(1, task, date);
    }

    public static TimerTask scheduleTask(int priority, Runnable task, Date date)
    {
        TimerTask timerTask = new ScheduledTask(priority, task);
        taskTimer.schedule(timerTask, date);
        return timerTask;
    }

    //在1delay秒后执行此任务,每次间隔2秒period
    public static TimerTask scheduleTask(Runnable task, long delay, long period)
    {
        return scheduleTask(1, task, delay, period);
    }

    public static TimerTask scheduleTask(int priority, Runnable task, long delay, long period)
    {
        TimerTask timerTask = new ScheduledTask(priority, task);
        taskTimer.scheduleAtFixedRate(timerTask, delay, period);
        return timerTask;
    }

    public static void shutdown()
    {
        taskTimer.cancel();
    }

    public static void restart()
    {
        taskTimer.cancel();
        initialize();
    }

    private static TaskWrapper nextTask()
    {
    	synchronized(lock){
    		while(taskQueue.isEmpty() || !started) 
    			try
    		{
    				lock.wait();
    		}
    		catch(InterruptedException ie) { }
    		return (TaskWrapper)taskQueue.dequeue();
    	}

    }

    private static void addWorker()
    {
        if(workers.length < 30 && System.currentTimeMillis() > newWorkerTimestamp + 2000L)
        {
            int newSize = workers.length + 1;
            int lastIndex = newSize - 1;
            TaskEngineWorker newWorkers[] = new TaskEngineWorker[newSize];
            System.arraycopy(workers, 0, newWorkers, 0, workers.length);
            newWorkers[lastIndex] = new TaskEngineWorker("Task Engine Worker " + lastIndex);
            newWorkers[lastIndex].setDaemon(true);
            newWorkers[lastIndex].start();
            workers = newWorkers;
            newWorkerTimestamp = System.currentTimeMillis();
        }
    }

    private static void removeWorker()
    {
        if(workers.length > 3 && System.currentTimeMillis() > busyTimestamp + 5000L)
        {
            workers[workers.length - 1].stopWorker();
            int newSize = workers.length - 1;
            TaskEngineWorker newWorkers[] = new TaskEngineWorker[newSize];
            System.arraycopy(workers, 0, newWorkers, 0, newSize);
            workers = newWorkers;
            busyTimestamp = System.currentTimeMillis();
        }
    }

    public static final int HIGH_PRIORITY = 2;
    public static final int MEDIUM_PRIORITY = 1;
    public static final int LOW_PRIORITY = 0;
    private static PriorityQueue taskQueue = null;
    private static ThreadGroup threadGroup;
    private static TaskEngineWorker workers[] = null;
    private static Timer taskTimer = null;
    private static Object lock = new Object();
    private static long newWorkerTimestamp = System.currentTimeMillis();
    private static long busyTimestamp = System.currentTimeMillis();
    private static boolean started = false;

    static 
    {
        initialize();
    }


}


2. TaskWrapper 任务包装类

 

package com.yanek.task;

public class TaskWrapper
{

    public TaskWrapper(int priority, Runnable task)
    {
        this.priority = priority;
        this.task = task;
    }

    public Runnable getTask()
    {
        return task;
    }

    public void setTask(Runnable task)
    {
        this.task = task;
    }

    public int getPriority()
    {
        return priority;
    }

    public void setPriority(int priority)
    {
        this.priority = priority;
    }

    private Runnable task;
    private int priority;
}


3. 测试任务类:

package com.yanek.task;

import org.apache.log4j.Logger;

//import com.aspboy.jxc.tcp.SocketClient;

public class TestTask implements Runnable
{
	
	static Logger Log = Logger.getLogger(TestTask.class.getName());
	public void run() 
	{
		
		System.out.println("time==="+System.currentTimeMillis());
			}

}


4. 监听器类: 启动时加载任务和启动任务

 

package com.yanek.task;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class TaskListener implements ServletContextListener {

	public static final long SECOND = 1000L;

	private ServletContext context;

	public TaskListener() {
		System.out.println("LifeCycleListener new ... ");
	}

	public void contextInitialized(ServletContextEvent event) {

		System.out.println("ServletContext Initialized... ");
		context = event.getServletContext();

		String prefix = event.getServletContext().getRealPath("/");
		System.out.println("root path===" + prefix);

				 TestTask testtask = new TestTask();
		 TaskEngine.scheduleTask(testtask, SECOND * 1, SECOND * 2);
		 TaskEngine.start();

	}

	public void contextDestroyed(ServletContextEvent event) {
		System.out.println("ServletContext Destroyed... ");
		TaskEngine.shutdown();
	}

}


最后在web.xml配置监听器类:

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
 xmlns="http://java.sun.com/xml/ns/javaee" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 
 
 <listener>
        <listener-class>com.yanek.task.TaskListener</listener-class>
    </listener>
 
 
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>


启动web容器,即可开始执行任务。

 

 

posted on 2013-09-03 19:59  新一  阅读(581)  评论(0编辑  收藏  举报

导航