1 43 package org.objectweb.jotm; 44 45 import java.util.Vector ; 46 47 51 class Clock extends Thread { 52 53 private TimerManager tmgr; 54 55 public Clock(TimerManager tmgr) { 56 super("JotmClock"); 57 if (TraceTm.jta.isDebugEnabled()) { 58 TraceTm.jta.debug("Clock constructor"); 59 } 60 61 this.tmgr = tmgr; 62 } 63 64 public void run() { 65 tmgr.clock(); 66 } 67 } 68 69 73 class Batch extends Thread { 74 75 private TimerManager tmgr; 76 77 public Batch(TimerManager tmgr) { 78 super("JotmBatch"); 79 if (TraceTm.jta.isDebugEnabled()) { 80 TraceTm.jta.debug("Batch constructor"); 81 } 82 83 this.tmgr = tmgr; 84 } 85 86 public void run() { 87 tmgr.batch(); 88 } 89 } 90 91 98 public class TimerManager { 99 100 private static Batch batchThread; 102 private static Clock clockThread; 103 104 private Vector timerList = new Vector (); 106 private Vector expiredList = new Vector (); 107 108 private static TimerManager unique = null; 109 private static boolean shuttingdown = false; 110 111 114 private TimerManager() { 115 batchThread = new Batch(this); 117 batchThread.setDaemon(true); 118 batchThread.start(); 119 clockThread = new Clock(this); 120 clockThread.setDaemon(true); 121 clockThread.start(); 122 } 123 124 127 public static TimerManager getInstance() { 128 if (unique == null) 129 unique = new TimerManager(); 130 return unique; 131 } 132 133 137 public static void stop(boolean force) { 138 if (TraceTm.jta.isDebugEnabled()) { 139 TraceTm.jta.debug("Stop TimerManager"); 140 } 141 142 TimerManager tmgr = getInstance(); 143 shuttingdown = true; 144 while (clockThread.isAlive() || batchThread.isAlive()) { 145 try { 146 Thread.sleep(100); 147 } catch (InterruptedException e) { 148 break; 149 } 150 } 151 if (TraceTm.jta.isDebugEnabled()) { 152 TraceTm.jta.debug("TimerManager has stopped"); 153 } 154 } 155 156 public static void stop() { 157 stop(true); 158 } 159 160 166 public void clock() { 167 while (true) { 168 try { 169 Thread.sleep(shuttingdown?1:1000); synchronized(timerList) { 172 int found = 0; 173 boolean empty = true; 174 for (int i = 0; i < timerList.size(); i++) { 175 TimerEvent t = (TimerEvent) timerList.elementAt(i); 176 if (!t.isStopped()) { 177 empty = false; 178 } 179 if (t.update() <= 0) { 180 timerList.removeElementAt(i--); 181 if (t.valid()) { 182 expiredList.addElement(t); 183 found++; 184 if (t.ispermanent() && !shuttingdown) { 185 t.restart(); 186 timerList.addElement(t); 187 } 188 } 189 } 190 t = null; 192 } 193 if (found > 0) { 194 timerList.notify(); 195 } else { 196 if (empty && shuttingdown) { 197 break; 198 } 199 } 200 } 201 } catch (InterruptedException e) { 202 TraceTm.jta.error("Timer interrupted"); 203 } 204 } 205 synchronized(timerList) { timerList.notify(); 207 } 208 } 209 210 213 public void batch() { 214 215 while (!(shuttingdown && timerList.isEmpty() && expiredList.isEmpty())) { 216 TimerEvent t; 217 synchronized(timerList) { 218 while (expiredList.isEmpty()) { 219 if (shuttingdown) return; 220 try { 221 timerList.wait(); 222 } catch (Exception e) { 223 TraceTm.jta.error("Exception in Batch: ", e); 224 } 225 } 226 t = (TimerEvent) expiredList.elementAt(0); 227 expiredList.removeElementAt(0); 228 } 229 t.process(); 231 } 232 } 233 234 241 public TimerEvent addTimer(TimerEventListener tel, long timeout, Object arg, boolean permanent) { 242 TimerEvent te = new TimerEvent(tel, timeout, arg, permanent); 243 synchronized(timerList) { 244 timerList.addElement(te); 245 } 246 return te; 247 } 248 249 254 public void removeTimer(TimerEvent te) { 255 synchronized(timerList) { 256 timerList.removeElement(te); 257 } 258 } 259 } 260 | Popular Tags |