1 14 15 package EDU.oswego.cs.dl.util.concurrent; 16 import java.util.Comparator ; 17 import java.util.Date ; 18 19 52 53 public class ClockDaemon extends ThreadFactoryUser { 54 55 56 57 protected final Heap heap_ = new Heap(DefaultChannelCapacity.get()); 58 59 60 protected static class TaskNode implements Comparable { 61 final Runnable command; final long period; private long timeToRun_; 65 69 private boolean cancelled_ = false; 70 71 74 synchronized void setCancelled() { cancelled_ = true; } 75 synchronized boolean getCancelled() { return cancelled_; } 76 77 synchronized void setTimeToRun(long w) { timeToRun_ = w; } 78 synchronized long getTimeToRun() { return timeToRun_; } 79 80 81 public int compareTo(Object other) { 82 long a = getTimeToRun(); 83 long b = ((TaskNode)(other)).getTimeToRun(); 84 return (a < b)? -1 : ((a == b)? 0 : 1); 85 } 86 87 TaskNode(long w, Runnable c, long p) { 88 timeToRun_ = w; command = c; period = p; 89 } 90 91 TaskNode(long w, Runnable c) { this(w, c, -1); } 92 } 93 94 95 102 public Object executeAt(Date date, Runnable command) { 103 TaskNode task = new TaskNode(date.getTime(), command); 104 heap_.insert(task); 105 restart(); 106 return task; 107 } 108 109 160 public Object executeAfterDelay(long millisecondsToDelay, Runnable command) { 161 long runtime = System.currentTimeMillis() + millisecondsToDelay; 162 TaskNode task = new TaskNode(runtime, command); 163 heap_.insert(task); 164 restart(); 165 return task; 166 } 167 168 224 public Object executePeriodically(long period, 225 Runnable command, 226 boolean startNow) { 227 228 if (period <= 0) throw new IllegalArgumentException (); 229 230 long firstTime = System.currentTimeMillis(); 231 if (!startNow) firstTime += period; 232 233 TaskNode task = new TaskNode(firstTime, command, period); 234 heap_.insert(task); 235 restart(); 236 return task; 237 } 238 239 252 public static void cancel(Object taskID) { 253 ((TaskNode)taskID).setCancelled(); 254 } 255 256 257 258 protected Thread thread_; 259 260 261 267 public synchronized Thread getThread() { 268 return thread_; 269 } 270 271 272 protected synchronized void clearThread() { 273 thread_ = null; 274 } 275 276 282 283 public synchronized void restart() { 284 if (thread_ == null) { 285 thread_ = threadFactory_.newThread(runLoop_); 286 thread_.start(); 287 } 288 else 289 notify(); 290 } 291 292 293 301 public synchronized void shutDown() { 302 heap_.clear(); 303 if (thread_ != null) 304 thread_.interrupt(); 305 thread_ = null; 306 } 307 308 309 protected synchronized TaskNode nextTask() { 310 311 313 try { 314 while (!Thread.interrupted()) { 315 316 318 TaskNode task = (TaskNode)(heap_.peek()); 319 320 if (task == null) { 321 wait(); 322 } 323 else { 324 long now = System.currentTimeMillis(); 325 long when = task.getTimeToRun(); 326 327 if (when > now) { wait(when - now); 329 } 330 else { 331 task = (TaskNode)(heap_.extract()); 332 333 if (!task.getCancelled()) { 335 if (task.period > 0) { task.setTimeToRun(now + task.period); 337 heap_.insert(task); 338 } 339 340 return task; 341 } 342 } 343 } 344 } 345 } 346 catch (InterruptedException ex) { } 348 return null; } 350 351 357 358 protected class RunLoop implements Runnable { 359 public void run() { 360 try { 361 for (;;) { 362 TaskNode task = nextTask(); 363 if (task != null) 364 task.command.run(); 365 else 366 break; 367 } 368 } 369 finally { 370 clearThread(); 371 } 372 } 373 } 374 375 protected final RunLoop runLoop_; 376 377 380 381 public ClockDaemon() { 382 runLoop_ = new RunLoop(); 383 } 384 385 386 387 } 388 | Popular Tags |