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

来源:互联网 发布:用友软件u8下载 编辑:程序博客网 时间:2024/06/05 11:58

主要包括如下几个类:

 

文章标题: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容器,即可开始执行任务。