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容器,即可开始执行任务。
java中基于TaskEngine类封装实现定时任务的更多相关文章
- Java中使用自定义类封装数组,添加类方法实现数据操作
1.具体见注释 2.后续或有更新 public class MyArray { private long[] array; private int cnt; // 自定义数组类的元素个数 /** 使用 ...
- Java中的Unsafe类111
1.Unsafe类介绍 Unsafe类是在sun.misc包下,不属于Java标准.但是很多Java的基础类库,包括一些被广泛使用的高性能开发库都是基于Unsafe类开发的,比如Netty.Hadoo ...
- Java中遍历实体类(处理MongoDB)
在实际过程中,经常要将实体类进行封装,尤其是处理数据库的过程中:因此,对于遍历实体类能够与数据库中的一行数据对应起来. 我是使用的环境是Spring boot,访问的数据库时MongoDB 实体类遍历 ...
- 【Java并发】Java中的原子操作类
综述 JDK从1.5开始提供了java.util.concurrent.atomic包. 通过包中的原子操作类能够线程安全地更新一个变量. 包含4种类型的原子更新方式:基本类型.数组.引用.对象中字段 ...
- 【Java】Java中的Collections类——Java中升级版的数据结构【转】
一般来说课本上的数据结构包括数组.单链表.堆栈.树.图.我这里所指的数据结构,是一个怎么表示一个对象的问题,有时候,单单一个变量声明不堪大用,比如int,String,double甚至一维数组.二维数 ...
- java中普通的顶级类是不能使用static关键字修饰的。只有内部类可以使用static修饰,也可以不使用staitc关键字修饰。
java中普通的顶级类是不能使用static关键字修饰的.只有内部类可以使用static修饰,也可以不使用staitc关键字修饰. java中的类可以是static吗?答案是可以.在java中我们可以 ...
- Java中的继承、封装、多态的理解
Java中的继承.封装.多态 继承的理解: 1.继承是面向对象的三大特征之一,也是实现代码复用的重要手段.Java的继承具有单继承的特点,每个子类只有一个直接父类. 2.Java的继承通过extend ...
- Java中的实体类--Serializable接口、transient 关键字
在java中,实体类是一个非常重要的概念,我们可以在实体类中封装对象.设置其属性和方法等.关于实体类,也经常涉及到适配器模式.装饰者模式等设计模式.那么在实际代码开发中,关于实体类的注意事项有哪些呢? ...
- Java中的Collections类
转载:https://blog.csdn.net/yangxingpa/article/details/80515963 从[Java]Java中的Collections类——Java中升级版的数据结 ...
随机推荐
- 使用GitBook编写文档
GitBook 简介 GitBook 是一个通过 Git 和 Markdown 来撰写书籍的工具,最终可以生成 3 种格式: 静态站点:包含了交互功能(例如搜索.书签)的站点 PDF:PDF 格式的文 ...
- JavaScript--对象+函数
1. 复杂数据类型 Object ECMAScript中的对象其实就是一组数据(属性)和功能(方法)的集合. 1) 创建Object实例: 1.使用构造函数创建,new Object() ...
- cocos2dx lua调用C++类.
最近需求所迫, 终于着手传说中的 lua 了. 折腾了4天, 总算大概搞明白了用法. 细节咱们就别谈了, 直接说项目里怎么跑起来. 准备工作 我们需要一系列繁琐的前奏. tolua++: 这是必备工具 ...
- USACO5.4-TeleCowmunication
题目大意:给出一个无向图,要求删除尽量少的点,使给定的2点间不再连通,并输出字典序最小的方案题型:图论-网络流此题难点在于建图,后面就是套网络流的模板.将点看成边,例如第i个点可以看成一条有向边< ...
- ASP.NET MVC中的模型绑定
模型绑定的本质 任何控制器方法的执行都受action invoker组件(下文用invoker代替)控制.对于每个Action方法的参数,这个invoker组件都会获取一个Model Binder ...
- underscorejs-invoke学习
2.13 invoke 2.13.1 语法: _.invoke(list, method, *args) 2.13.2 说明: 每个list属性值都执行method方法,根据method方法返回一个数 ...
- 19 Remove Nth Node From End of List(去掉链表中倒数第n个节点Easy)
题目意思:去掉链表中倒数第n个节点 思路:1.两次遍历,没什么技术含量,第一次遍历计算长度,第二次遍历找到倒数第k个,代码不写了 2.一次遍历,两个指针,用指针间的距离去计算. ps:特别注意删掉 ...
- 如何让IIS 8.0支持无后缀图片的访问
进入“MIME类型”模块后,我们点击右侧的“添加”,然后填好文件扩展名和类型值.对于无后缀的图片文件,扩展名只需填写“点”符号即可,类型值根据图片文件实际的扩展名填写.如果是jpeg格式的,那么就填写 ...
- 每日一算法【one】
//有一个数组 {1,2,3,4,5,6,7,8,9,12,13,45,67,89,99,101,111,123,134,565,677} 查找数组中是否有指定的某一个数. /** *------- ...
- k-近邻算法理解
左图中,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四 ...