1 28 29 30 package org.objectweb.jonas_timer; 31 32 import java.util.ArrayList ; 33 import java.util.Collection ; 34 import java.util.Iterator ; 35 36 import org.objectweb.util.monolog.api.BasicLevel; 37 38 42 class Clock extends Thread { 43 44 private TimerManager tmgr; 45 46 public Clock(TimerManager tmgr) { 47 super("JonasClock"); 48 if (TraceTimer.isDebug()) { 49 TraceTimer.logger.log(BasicLevel.DEBUG, "Clock constructor"); 50 } 51 this.tmgr = tmgr; 52 } 53 54 public void run() { 55 tmgr.clock(); 56 } 57 } 58 59 63 class Batch extends Thread { 64 65 private TimerManager tmgr; 66 67 public Batch(TimerManager tmgr) { 68 super("JonasBatch"); 69 if (TraceTimer.isDebug()) { 70 TraceTimer.logger.log(BasicLevel.DEBUG, "Batch constructor"); 71 } 72 this.tmgr = tmgr; 73 } 74 75 public void run() { 76 tmgr.batch(); 77 } 78 } 79 80 87 public class TimerManager { 88 89 private static Batch batchThread; 91 private static Clock clockThread; 92 93 private final static long PERIOD_MAX = 30000; private final static long PERIOD_MIN = 100; private long period; 96 private long minremtime = PERIOD_MAX; 97 98 private ArrayList timerList = new ArrayList (); 100 private ArrayList expiredList = new ArrayList (); 101 102 private static TimerManager unique = null; 103 private static boolean shuttingdown = false; 104 105 108 private TimerManager() { 109 batchThread = new Batch(this); 111 batchThread.start(); 112 clockThread = new Clock(this); 113 clockThread.start(); 114 } 115 116 119 public static TimerManager getInstance() { 120 if (unique == null) 121 unique = new TimerManager(); 122 return unique; 123 } 124 125 129 public static void stop(boolean force) { 130 if (TraceTimer.isDebug()) { 131 TraceTimer.logger.log(BasicLevel.DEBUG,"Stop TimerManager"); 132 } 133 TimerManager tmgr = getInstance(); 134 shuttingdown = true; 135 while (clockThread.isAlive() || batchThread.isAlive()) { 136 try { 137 Thread.sleep(100); 138 } catch (InterruptedException e) { 139 break; 140 } 141 } 142 if (TraceTimer.isDebug()) { 143 TraceTimer.logger.log(BasicLevel.DEBUG,"TimerManager has stopped"); 144 } 145 } 146 147 public static void stop() { 148 stop(true); 149 } 150 151 152 157 public void clock() { 158 synchronized(timerList) { 159 while (true) { 160 if (shuttingdown) { 162 period = 1; 163 } else { 164 period = PERIOD_MAX; 165 if (minremtime < period) { 166 period = minremtime < PERIOD_MIN ? PERIOD_MIN : minremtime; 167 } 168 } 169 try { 171 timerList.wait(period); 172 } catch (InterruptedException e) { 173 TraceTimer.logger.log(BasicLevel.ERROR, "Timer interrupted"); 174 } 175 int found = 0; 176 boolean empty = true; 177 minremtime = PERIOD_MAX; 178 for (Iterator i = timerList.iterator(); i.hasNext(); ) { 179 TimerEvent t = (TimerEvent) i.next(); 180 if (!t.isStopped()) { 181 empty = false; 182 } 183 long remtime = t.update(); 184 if (remtime <= 0) { 185 if (t.valid()) { 186 expiredList.add(t); 187 found++; 188 if (t.ispermanent() && !shuttingdown) { 189 remtime = t.restart(); 190 if (remtime < minremtime) { 191 minremtime = remtime; 192 } 193 } else { 194 i.remove(); 195 } 196 } else { 197 i.remove(); 198 } 199 } else { 200 if (remtime < minremtime) { 201 minremtime = remtime; 202 } 203 } 204 t = null; 206 } 207 if (found > 0) { 208 timerList.notifyAll(); 209 } else { 210 if (empty) { 211 if (shuttingdown) { 212 break; 213 } 214 } 215 } 216 } 217 timerList.notifyAll(); 218 } 219 } 220 221 224 public void batch() { 225 226 while (!(shuttingdown && timerList.isEmpty() && expiredList.isEmpty())) { 227 TimerEvent t; 228 synchronized(timerList) { 229 while (expiredList.isEmpty()) { 230 if (shuttingdown) { 231 TraceTimer.logger.log(BasicLevel.WARN, "TimerManager shutting down"); 232 return; 233 } 234 try { 235 timerList.wait(); 236 } catch (Exception e) { 237 TraceTimer.logger.log(BasicLevel.ERROR, "Exception in Batch: ",e); 238 } 239 } 240 t = (TimerEvent) expiredList.remove(0); 241 } 242 try { 244 t.process(); 245 } catch (Exception e) { 246 TraceTimer.logger.log(BasicLevel.WARN, "Ignoring exception: " + e); 248 e.printStackTrace(); 249 } 250 } 251 TraceTimer.logger.log(BasicLevel.WARN, "TimerManager stopped"); 252 } 253 254 262 public TimerEvent addTimer(TimerEventListener tel, long timeout, Object arg, boolean permanent) { 263 return addTimerMs(tel, timeout * 1000, arg, permanent); 264 } 265 266 273 public TimerEvent addTimerMs(TimerEventListener tel, long timeout, Object arg, boolean permanent) { 274 TimerEvent te = new TimerEvent(tel, timeout, arg, permanent); 275 synchronized(timerList) { 276 timerList.add(te); 277 if (timeout < minremtime) { 278 minremtime = timeout; 279 } 280 timerList.notifyAll(); 281 } 282 return te; 283 } 284 285 290 public void removeTimer(TimerEvent te) { 291 synchronized(timerList) { 292 timerList.remove(timerList.indexOf(te)); 293 } 294 } 295 } 296 | Popular Tags |