1 21 package fr.dyade.aaa.util; 22 23 import java.util.Vector ; 24 25 import org.objectweb.util.monolog.api.BasicLevel; 26 27 32 public class Timer { 33 34 private boolean cancelled = false; 35 36 TimerDaemon daemon; 37 38 Vector tasks; 39 40 41 public Timer() { 42 tasks = new Vector (); 43 daemon = new TimerDaemon(this); 44 } 45 46 55 public synchronized void schedule(TimerTask task, long delay) 56 throws Exception { 57 if (cancelled) 58 throw new IllegalStateException ("Timer has been cancelled."); 59 if (tasks.contains(task)) 60 throw new IllegalStateException ("Task is already scheduled."); 61 if (task.cancelled) 62 throw new IllegalStateException ("Task has been cancelled."); 63 64 if (delay < 0) 65 throw new IllegalArgumentException ("Invalid negative delay: " + delay); 66 67 long wakeupTime = System.currentTimeMillis() + delay; 68 insertTask(task, wakeupTime); 69 if (!daemon.started) 70 daemon.start(); 71 this.notify(); 72 73 } 74 75 76 public synchronized void cancel() { 77 cancelled = true; 78 79 if (!daemon.started) return; 80 tasks.removeAllElements(); 81 daemon.running = false; 82 daemon.shutdown(); 83 } 84 85 86 private void insertTask(TimerTask task, long wakeupTime) { 87 task.timer = this; 88 task.wakeupTime = wakeupTime; 89 90 int i = 0; 91 TimerTask currentTask; 92 while (i < tasks.size()) { 93 currentTask = (TimerTask) tasks.elementAt(i); 94 95 if (currentTask.wakeupTime > wakeupTime) { 96 tasks.insertElementAt(task, i); 97 break; 98 } else 99 i++; 100 } 101 if (i == tasks.size()) 102 tasks.addElement(task); 103 104 } 105 } 106 107 108 class TimerDaemon extends Daemon { 109 110 private Timer timer; 111 112 long nextWakeup = -1; 113 114 boolean started = false; 115 116 117 TimerDaemon(Timer timer) { 118 super("timer"); 119 setDaemon(true); 120 this.timer = timer; 121 } 122 123 124 public void start() { 125 super.start(); 126 started = true; 127 } 128 129 130 public void run() { 131 try { 132 TimerTask task = null; 133 while (running) { 134 canStop = true; 135 136 task = null; 137 try { 138 synchronized (timer) { 139 if (timer.tasks.isEmpty()) { 140 logmon.log(BasicLevel.DEBUG, 141 getName() + ", run and wait()"); 142 timer.wait(); 143 } else { 144 task = (TimerTask) timer.tasks.elementAt(0); 145 nextWakeup = task.wakeupTime; 146 long sleepPeriod = nextWakeup - System.currentTimeMillis(); 147 if (sleepPeriod <= 0) { 148 150 logmon.log(BasicLevel.DEBUG, 151 getName() + ", run, remove task and continue"); 152 timer.tasks.removeElementAt(0); 153 canStop = false; 154 } else { 155 logmon.log(BasicLevel.DEBUG, 157 getName() + ", run and wait("+sleepPeriod+")"); 158 task.waiting = true; 159 timer.wait(sleepPeriod); 160 task = null; 161 } 162 } 163 164 } 165 if (task != null) { 166 canStop = false; 167 task.run(); 169 task = null; 170 } 171 } catch (InterruptedException e1) { 172 logmon.log(BasicLevel.DEBUG, 174 getName() + ", run," + e1.toString()); 175 } 176 177 } 178 started = false; 179 } catch (Exception e) { 180 logmon.log(BasicLevel.WARN, 181 getName() + ", run," + e.toString()); 182 } finally { 183 finish(); 184 } 185 } 186 187 188 public synchronized void interrupt() { 189 if (canStop) 190 thread.interrupt(); 191 } 192 193 194 public void shutdown() { 195 timer.notify(); 196 } 197 198 199 public void close() { 200 } 201 } 202 | Popular Tags |