JAVA技巧(JOTM中定时器的源码分析) |
|
www.nanhushi.com 佚名 不详 |
在Jotm中看到一个很齐全的定时器,贴出来以防备用; package org.objectweb.jotm; import java.util.Vector; /** * *对计时器列表中的计时器进行倒计时 */ class Clock extends Thread { private TimerManager tmgr; public Clock(TimerManager tmgr) { super("JotmClock"); if (TraceTm.jta.isDebugEnabled()) { TraceTm.jta.debug("Clock constructor"); } this.tmgr = tmgr; } public void run() { tmgr.clock(); } } /** * *Examda提示:出去计时器列表中的过期计时器,如倒计时为负数 */ class Batch extends Thread { private TimerManager tmgr; public Batch(TimerManager tmgr) { super("JotmBatch"); if (TraceTm.jta.isDebugEnabled()) { TraceTm.jta.debug("Batch constructor"); } this.tmgr = tmgr; } public void run() { tmgr.batch(); } } /** *含有两个计时器列表,并且含有两个线程,一个线程进行计时器的倒计时, *一个线程移除过期计时器并且执行计时器的监听器动作; */ public class TimerManager { // threads managing the service. private static Batch batchThread; private static Clock clockThread; // lists //计时器列表 private Vector timerList = new Vector(); //过期计时器列表 private Vector expiredList = new Vector(); //单例 private static TimerManager unique = null; private static boolean shuttingdown = false; /** * Constructor */ private TimerManager() { // launch threads for timers batchThread = new Batch(this); batchThread.setDaemon(true); batchThread.start(); clockThread = new Clock(this); clockThread.setDaemon(true); clockThread.start(); } /** * 这个时间管理器是一个单例类; */ public static TimerManager getInstance() { if (unique == null) unique = new TimerManager(); return unique; } //停止时间管理器中的计时器; public static void stop(boolean force) { if (TraceTm.jta.isDebugEnabled()) { TraceTm.jta.debug("Stop TimerManager"); } TimerManager tmgr = getInstance(); shuttingdown = true; while (clockThread.isAlive() || batchThread.isAlive()) { try { Thread.sleep(100); } catch (InterruptedException e) { break; } } if (TraceTm.jta.isDebugEnabled()) { TraceTm.jta.debug("TimerManager has stopped"); } } public static void stop() { stop(true); } /** * cney speed up the clock x1000 when shutting down * update all timers in the list * each timer expired is put in a special list of expired timers * they will be processed then by the Batch Thread. */
public void clock() { //无限循环 while (true) { try { //线程休息一秒 Thread.sleep(shuttingdown?1:1000); // 1 second or 1ms shen shuttingdown // Thread.currentThread().sleep(shuttingdown?1:1000); // 1 second or 1ms shen shuttingdown synchronized(timerList) { int found = 0; boolean empty = true; for (int i = 0; i < timerList.size(); i++) { TimerEvent t = (TimerEvent) timerList.elementAt(i); //如果没有活动的计时器,那么计时器队列为空; if (!t.isStopped()) { empty = false; } //如果计时器过期 if (t.update() <= 0) { //从计时器队列中移除 timerList.removeElementAt(i--); if (t.valid()) { //该计时器存在计时器监听器的话,把这个计时器加入过期计时器 //如果不存在,则废除,哪个队列都不加入 expiredList.addElement(t); found++; //如果持续的话,则继续把该计时器再次加入计时器队列中 if (t.ispermanent() && !shuttingdown) { t.restart(); timerList.addElement(t); } } } // Be sure there is no more ref on bean in this local variable. t = null; } if (found > 0) { //唤醒线程; timerList.notify(); } else { if (empty && shuttingdown) { break; } } } } catch (InterruptedException e) { TraceTm.jta.error("Timer interrupted"); } } synchronized(timerList) { // notify batch so that function can return. timerList.notify(); } } /** * process all expired timers */ public void batch() { while (!(shuttingdown && timerList.isEmpty() && expiredList.isEmpty())) { TimerEvent t; synchronized(timerList) { while (expiredList.isEmpty()) { if (shuttingdown) return; try { //计时器计时线程让如果找到到期的计时器,那么就会唤醒执行该计时器的线程执行监听器动作 timerList.wait(); } catch (Exception e) { TraceTm.jta.error("Exception in Batch: ", e); } } t = (TimerEvent) expiredList.elementAt(0); expiredList.removeElementAt(0); } //执行动作; t.process(); } } /** * add a new timer in the list * @param tel Object that will be notified when the timer expire. * @param timeout nb of seconds before the timer expires. * @param arg info passed with the timer * @param permanent true if the timer is permanent. */ public TimerEvent addTimer(TimerEventListener tel, long timeout, Object arg, boolean permanent) { TimerEvent te = new TimerEvent(tel, timeout, arg, permanent); synchronized(timerList) { timerList.addElement(te); } return te; } /** * remove a timer from the list. this is not very efficient. * A better way to do this is TimerEvent.unset() * @deprecated */ public void removeTimer(TimerEvent te) { synchronized(timerList) { timerList.removeElement(te); } } }
|
|
|
文章录入:杜斌 责任编辑:杜斌 |
|
上一篇文章: JAVA技巧(javawebservice在resin中实现) 下一篇文章: JAVA技巧(找出一个数组中出现次数最多的那个元素) |
【字体:小 大】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 |
|
|