主要包括如下几个类:

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

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

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

1. 核心工具类: TaskEngine

  1. package com.yanek.task;
  2.  
  3. import java.util.*;
  4. import java.util.LinkedList;
  5.  
  6. import org.apache.log4j.Logger;
  7.  
  8. public class TaskEngine
  9. {
  10. static Logger logger = Logger.getLogger(TaskEngine.class.getName());
  11. private static class PriorityQueue
  12. {
  13.  
  14. public void enqueue(int priority, Object object)
  15. {
  16. if(priority > HIGH_PRIORITY)
  17. priority = HIGH_PRIORITY;
  18. else
  19. if(priority < LOW_PRIORITY)
  20. priority = LOW_PRIORITY;
  21. switch(priority)
  22. {
  23. case HIGH_PRIORITY: // '\002'
  24. high.addFirst(object);
  25. break;
  26.  
  27. case MEDIUM_PRIORITY: // '\001'
  28. medium.addFirst(object);
  29. break;
  30.  
  31. case LOW_PRIORITY: // '\0'
  32. low.addFirst(object);
  33. break;
  34. }
  35. }
  36.  
  37. public boolean isEmpty()
  38. {
  39. return high.isEmpty() && medium.isEmpty() && low.isEmpty();
  40. }
  41.  
  42. public int size()
  43. {
  44. return high.size() + medium.size() + low.size();
  45. }
  46.  
  47. public Object dequeue()
  48. {
  49. Object object;
  50. if(!high.isEmpty())
  51. object = high.removeLast();
  52. else
  53. if(!medium.isEmpty())
  54. object = medium.removeLast();
  55. else
  56. if(!low.isEmpty())
  57. object = low.removeLast();
  58. else
  59. throw new NoSuchElementException("Queue is empty.");
  60. if(!low.isEmpty())
  61. medium.addFirst(low.removeLast());
  62. if(!medium.isEmpty())
  63. high.addFirst(medium.removeLast());
  64. return object;
  65. }
  66.  
  67. private LinkedList high;
  68. private LinkedList medium;
  69. private LinkedList low;
  70.  
  71. private PriorityQueue()
  72. {
  73. high = new LinkedList();
  74. medium = new LinkedList();
  75. low = new LinkedList();
  76. }
  77.  
  78. }
  79.  
  80. private static class ScheduledTask extends TimerTask
  81. {
  82.  
  83. public void run()
  84. {
  85. TaskEngine.addTask(priority, task);
  86. }
  87.  
  88. private int priority;
  89. private Runnable task;
  90.  
  91. ScheduledTask(int priority, Runnable task)
  92. {
  93. this.priority = priority;
  94. this.task = task;
  95. }
  96. }
  97.  
  98. private static class TaskEngineWorker extends Thread
  99. {
  100.  
  101. public void stopWorker()
  102. {
  103. done = true;
  104. }
  105.  
  106. public void run()
  107. {
  108. do
  109. {
  110. if(done)
  111. break;
  112. int currentThreadPriority = getPriority();
  113. int newThreadPriority = currentThreadPriority;
  114. try
  115. {
  116. TaskWrapper wrapper = TaskEngine.nextTask();
  117. int desiredTaskPriority = wrapper.getPriority();
  118. newThreadPriority = desiredTaskPriority != 2 ? ((int) (desiredTaskPriority != 1 ? 2 : 5)) : 9;
  119. if(newThreadPriority != currentThreadPriority)
  120. try
  121. {
  122. logger.debug("Running task engine worker (" + wrapper.getTask().getClass() + ") at thread priority " + newThreadPriority);
  123. setPriority(newThreadPriority);
  124. }
  125. catch(Exception e)
  126. {
  127. logger.error(e);
  128. }
  129. logger.debug("Executing task (" + wrapper.getTask().getClass() + ")");
  130. wrapper.getTask().run();
  131. logger.debug("Completed execution task (" + wrapper.getTask().getClass() + ")");
  132. if(newThreadPriority != currentThreadPriority)
  133. try
  134. {
  135. logger.debug("Restoring task engine worker thread to thread priority - " + currentThreadPriority);
  136. setPriority(currentThreadPriority);
  137. }
  138. catch(Exception e)
  139. {
  140. logger.error(e);
  141. }
  142. }
  143. catch(Exception e)
  144. {
  145. logger.error(e);
  146. if(newThreadPriority != currentThreadPriority)
  147. try
  148. {
  149. logger.debug("Restoring task engine worker thread to thread priority - " + currentThreadPriority);
  150. setPriority(currentThreadPriority);
  151. }
  152. catch(Exception e2)
  153. {
  154. logger.error(e2);
  155. }
  156. }
  157. } while(true);
  158. }
  159.  
  160. private boolean done;
  161.  
  162. TaskEngineWorker(String name)
  163. {
  164. super(TaskEngine.threadGroup, name);
  165. done = false;
  166. }
  167. }
  168.  
  169. private TaskEngine()
  170. {
  171. }
  172.  
  173. public static void start()
  174. {
  175. synchronized(lock)
  176. {
  177. started = true;
  178. lock.notifyAll();
  179. }
  180. }
  181.  
  182. private static void initialize()
  183. {
  184. taskTimer = new Timer(true);
  185. taskQueue = new PriorityQueue();
  186. threadGroup = new ThreadGroup("Task Engine Workers");
  187. workers = new TaskEngineWorker[5];
  188. for(int i = 0; i < workers.length; i++)
  189. {
  190. workers[i] = new TaskEngineWorker("Task Engine Worker " + i);
  191. workers[i].setDaemon(true);
  192. workers[i].start();
  193. }
  194.  
  195. }
  196.  
  197. public static int size()
  198. {
  199. synchronized(lock){
  200. return taskQueue.size();
  201. }
  202.  
  203. }
  204.  
  205. public static int getNumWorkers()
  206. {
  207. return workers.length;
  208. }
  209.  
  210. public static void addTask(Runnable task)
  211. {
  212. addTask(1, task);
  213. }
  214.  
  215. public static void addTask(int priority, Runnable task)
  216. {
  217. synchronized(lock)
  218. {
  219. if((double)taskQueue.size() > Math.ceil(workers.length / 2))
  220. {
  221. busyTimestamp = System.currentTimeMillis();
  222. addWorker();
  223. } else
  224. if(workers.length > 3)
  225. removeWorker();
  226. TaskWrapper wrapper = new TaskWrapper(priority, task);
  227. taskQueue.enqueue(priority, wrapper);
  228. lock.notify();
  229. }
  230. }
  231.  
  232. public static TimerTask scheduleTask(Runnable task, Date date)
  233. {
  234. return scheduleTask(1, task, date);
  235. }
  236.  
  237. public static TimerTask scheduleTask(int priority, Runnable task, Date date)
  238. {
  239. TimerTask timerTask = new ScheduledTask(priority, task);
  240. taskTimer.schedule(timerTask, date);
  241. return timerTask;
  242. }
  243.  
  244. //在1delay秒后执行此任务,每次间隔2秒period
  245. public static TimerTask scheduleTask(Runnable task, long delay, long period)
  246. {
  247. return scheduleTask(1, task, delay, period);
  248. }
  249.  
  250. public static TimerTask scheduleTask(int priority, Runnable task, long delay, long period)
  251. {
  252. TimerTask timerTask = new ScheduledTask(priority, task);
  253. taskTimer.scheduleAtFixedRate(timerTask, delay, period);
  254. return timerTask;
  255. }
  256.  
  257. public static void shutdown()
  258. {
  259. taskTimer.cancel();
  260. }
  261.  
  262. public static void restart()
  263. {
  264. taskTimer.cancel();
  265. initialize();
  266. }
  267.  
  268. private static TaskWrapper nextTask()
  269. {
  270. synchronized(lock){
  271. while(taskQueue.isEmpty() || !started)
  272. try
  273. {
  274. lock.wait();
  275. }
  276. catch(InterruptedException ie) { }
  277. return (TaskWrapper)taskQueue.dequeue();
  278. }
  279.  
  280. }
  281.  
  282. private static void addWorker()
  283. {
  284. if(workers.length < 30 && System.currentTimeMillis() > newWorkerTimestamp + 2000L)
  285. {
  286. int newSize = workers.length + 1;
  287. int lastIndex = newSize - 1;
  288. TaskEngineWorker newWorkers[] = new TaskEngineWorker[newSize];
  289. System.arraycopy(workers, 0, newWorkers, 0, workers.length);
  290. newWorkers[lastIndex] = new TaskEngineWorker("Task Engine Worker " + lastIndex);
  291. newWorkers[lastIndex].setDaemon(true);
  292. newWorkers[lastIndex].start();
  293. workers = newWorkers;
  294. newWorkerTimestamp = System.currentTimeMillis();
  295. }
  296. }
  297.  
  298. private static void removeWorker()
  299. {
  300. if(workers.length > 3 && System.currentTimeMillis() > busyTimestamp + 5000L)
  301. {
  302. workers[workers.length - 1].stopWorker();
  303. int newSize = workers.length - 1;
  304. TaskEngineWorker newWorkers[] = new TaskEngineWorker[newSize];
  305. System.arraycopy(workers, 0, newWorkers, 0, newSize);
  306. workers = newWorkers;
  307. busyTimestamp = System.currentTimeMillis();
  308. }
  309. }
  310.  
  311. public static final int HIGH_PRIORITY = 2;
  312. public static final int MEDIUM_PRIORITY = 1;
  313. public static final int LOW_PRIORITY = 0;
  314. private static PriorityQueue taskQueue = null;
  315. private static ThreadGroup threadGroup;
  316. private static TaskEngineWorker workers[] = null;
  317. private static Timer taskTimer = null;
  318. private static Object lock = new Object();
  319. private static long newWorkerTimestamp = System.currentTimeMillis();
  320. private static long busyTimestamp = System.currentTimeMillis();
  321. private static boolean started = false;
  322.  
  323. static
  324. {
  325. initialize();
  326. }
  327.  
  328. }

2. TaskWrapper 任务包装类

  1. package com.yanek.task;
  2.  
  3. public class TaskWrapper
  4. {
  5.  
  6. public TaskWrapper(int priority, Runnable task)
  7. {
  8. this.priority = priority;
  9. this.task = task;
  10. }
  11.  
  12. public Runnable getTask()
  13. {
  14. return task;
  15. }
  16.  
  17. public void setTask(Runnable task)
  18. {
  19. this.task = task;
  20. }
  21.  
  22. public int getPriority()
  23. {
  24. return priority;
  25. }
  26.  
  27. public void setPriority(int priority)
  28. {
  29. this.priority = priority;
  30. }
  31.  
  32. private Runnable task;
  33. private int priority;
  34. }

3. 测试任务类:

  1. package com.yanek.task;
  2.  
  3. import org.apache.log4j.Logger;
  4.  
  5. //import com.aspboy.jxc.tcp.SocketClient;
  6.  
  7. public class TestTask implements Runnable
  8. {
  9.  
  10. static Logger Log = Logger.getLogger(TestTask.class.getName());
  11. public void run()
  12. {
  13.  
  14. System.out.println("time==="+System.currentTimeMillis());
  15. }
  16.  
  17. }

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

  1. package com.yanek.task;
  2.  
  3. import javax.servlet.ServletContext;
  4. import javax.servlet.ServletContextEvent;
  5. import javax.servlet.ServletContextListener;
  6.  
  7. public class TaskListener implements ServletContextListener {
  8.  
  9. public static final long SECOND = 1000L;
  10.  
  11. private ServletContext context;
  12.  
  13. public TaskListener() {
  14. System.out.println("LifeCycleListener new ... ");
  15. }
  16.  
  17. public void contextInitialized(ServletContextEvent event) {
  18.  
  19. System.out.println("ServletContext Initialized... ");
  20. context = event.getServletContext();
  21.  
  22. String prefix = event.getServletContext().getRealPath("/");
  23. System.out.println("root path===" + prefix);
  24.  
  25. TestTask testtask = new TestTask();
  26. TaskEngine.scheduleTask(testtask, SECOND * 1, SECOND * 2);
  27. TaskEngine.start();
  28.  
  29. }
  30.  
  31. public void contextDestroyed(ServletContextEvent event) {
  32. System.out.println("ServletContext Destroyed... ");
  33. TaskEngine.shutdown();
  34. }
  35.  
  36. }

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

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app version="2.5"
  3. xmlns="http://java.sun.com/xml/ns/javaee"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  6. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  7.  
  8. <listener>
  9. <listener-class>com.yanek.task.TaskListener</listener-class>
  10. </listener>
  11.  
  12. <welcome-file-list>
  13. <welcome-file>index.jsp</welcome-file>
  14. </welcome-file-list>
  15. </web-app>

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

java中基于TaskEngine类封装实现定时任务的更多相关文章

  1. Java中使用自定义类封装数组,添加类方法实现数据操作

    1.具体见注释 2.后续或有更新 public class MyArray { private long[] array; private int cnt; // 自定义数组类的元素个数 /** 使用 ...

  2. Java中的Unsafe类111

    1.Unsafe类介绍 Unsafe类是在sun.misc包下,不属于Java标准.但是很多Java的基础类库,包括一些被广泛使用的高性能开发库都是基于Unsafe类开发的,比如Netty.Hadoo ...

  3. Java中遍历实体类(处理MongoDB)

    在实际过程中,经常要将实体类进行封装,尤其是处理数据库的过程中:因此,对于遍历实体类能够与数据库中的一行数据对应起来. 我是使用的环境是Spring boot,访问的数据库时MongoDB 实体类遍历 ...

  4. 【Java并发】Java中的原子操作类

    综述 JDK从1.5开始提供了java.util.concurrent.atomic包. 通过包中的原子操作类能够线程安全地更新一个变量. 包含4种类型的原子更新方式:基本类型.数组.引用.对象中字段 ...

  5. 【Java】Java中的Collections类——Java中升级版的数据结构【转】

    一般来说课本上的数据结构包括数组.单链表.堆栈.树.图.我这里所指的数据结构,是一个怎么表示一个对象的问题,有时候,单单一个变量声明不堪大用,比如int,String,double甚至一维数组.二维数 ...

  6. java中普通的顶级类是不能使用static关键字修饰的。只有内部类可以使用static修饰,也可以不使用staitc关键字修饰。

    java中普通的顶级类是不能使用static关键字修饰的.只有内部类可以使用static修饰,也可以不使用staitc关键字修饰. java中的类可以是static吗?答案是可以.在java中我们可以 ...

  7. Java中的继承、封装、多态的理解

    Java中的继承.封装.多态 继承的理解: 1.继承是面向对象的三大特征之一,也是实现代码复用的重要手段.Java的继承具有单继承的特点,每个子类只有一个直接父类. 2.Java的继承通过extend ...

  8. Java中的实体类--Serializable接口、transient 关键字

    在java中,实体类是一个非常重要的概念,我们可以在实体类中封装对象.设置其属性和方法等.关于实体类,也经常涉及到适配器模式.装饰者模式等设计模式.那么在实际代码开发中,关于实体类的注意事项有哪些呢? ...

  9. Java中的Collections类

    转载:https://blog.csdn.net/yangxingpa/article/details/80515963 从[Java]Java中的Collections类——Java中升级版的数据结 ...

随机推荐

  1. Listbox与dataGridView的获取鼠标点击事件的区别!!!

    lisxian.SelectedIndex = index; Listbox获取鼠标的代码!!!! DataGridViewRow currenRow = this.dgvxian3.Rows[ind ...

  2. Python文件之----JSON

    #coding=utf-8import json def writeJSON(filaName="test.json"): f=open(filaName, "wb&qu ...

  3. 【USACO 3.2.3】纺车的轮子

    [描述] 一架纺车有五个纺轮,这五个不透明的轮子边缘上都有一些缺口.这些缺口必须被迅速而准确地排列好.每个轮子都有一个起始标记(在0度),这样所有的轮子都可以在统一的已知位置开始转动.轮子按照角度变大 ...

  4. 交叉编译:cannot find /lib/libc.so.6 collect2: ld returned 1 exit status

    1.有时候明明指定了交叉编译的动态库搜索路径,但有些库提示还是搜索不到,而且提示的搜索路径有点奇怪,不是指定的路径,比如: /opt/mips-4.4/bin/../lib/gcc/mips-linu ...

  5. 关闭C#主窗体弹出是否关闭对话框

    在开发系统时,常常有这样一个问题,就是当关闭主窗体,也即退出系统时,如果想提示是否关闭,以免误操作,可以在主窗体的Main_FormClosing事件中添加一个对话框,代码如下: private vo ...

  6. 88 Merge Sorted Array(归并排序Easy)

    题目意思:num1和num2均为递增数组,对其进行递增排序存到num1中 class Solution { public: void merge(vector<int>& nums ...

  7. 解决SQL Server Management Studio Express不支持更新全文目录的方法

    微软的说法:https://msdn.microsoft.com/zh-cn/library/ms365247.aspx 可以用命令创建: A.创建唯一索引.全文目录和全文索引 以下示例对 Adven ...

  8. 大脑皮层是如何工作的 《人工智能的未来》(<On intelligence>)读书笔记

    PS:今年寒假的读书笔记,挖下的坑已无力再填...不过有关智能和人工智能的书还是要继续读的~ 正文: 我觉得书名翻译不是很确切,全书讨论的核心应该更是在“真”智能:讨论对人脑智能的理解,可以怎样帮助我 ...

  9. 水仙花 AC 杭电

    水仙花数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  10. UvaLive 6661 Equal Sum Sets (DFS)

    Let us consider sets of positive integers less than or equal to n. Note that all elements of a set a ...