package com.idega.util.timer; /** * This class manages the thread which sleeps until the next timer. * Methods are synchronized to prevent interference fromthe TimerThread thread * and external threads. * * @author Olivier Dedieu, David Sims, Jim Lerner * @version 1.4, 01/02/2002 * @modified Eirikur Hrafnsson eiki@idega.is */ public class TimerThread implements Runnable { protected TimerManager mgr; protected Thread thread; private long sleepUntil = -1; private boolean debug = false; private boolean shutdown = false; private void debug(String s) { if (this.debug) { System.out.println("[" + Thread.currentThread().getName() + "] TimerThread: " + s); } } /** * Creates a new TimerThread. * * @param isDaemon true if the waiter thread should run as a daemon. * @param threadName the name of the waiter thread */ public TimerThread(TimerManager mgr, boolean isDaemon, String waiterName) { this.mgr = mgr; // start the thread this.thread = new Thread(this, waiterName); this.thread.setDaemon(isDaemon); this.thread.start(); } /** * Updates the time to sleep. * * @param sleepUntil the new time to sleep until. */ public synchronized void update(long sleepUntil) { this.sleepUntil = sleepUntil; debug("Update for " + sleepUntil); // timeToSleep); debug("I notify the thread to update its sleeping time"); notify(); } /** * Restarts the thread for a new time to sleep until. * * @param sleepUntil the new time to sleep until. */ public synchronized void restart(long sleepUntil) { this.sleepUntil = sleepUntil; notify(); } /** * Stops (destroy) the thread. */ public synchronized void stop() { this.shutdown = true; notify(); } public synchronized void run() { debug("I'm running"); while(!this.shutdown) { try { // check if there's timer here if (this.sleepUntil <= 0) { // no timer here. So wait for a new timer to come along. wait(); } // if else { // yes, there's an timer here. Wait until the timer is ready. long timeout = this.sleepUntil - System.currentTimeMillis(); if (timeout > 0) { wait(timeout); } // if } // if // now that we've awakened again, check if an timer is due (within // 1 second) if (this.sleepUntil >= 0 && (this.sleepUntil - System.currentTimeMillis() < 1000)) { // yes, an timer is ready. Notify the listeners. this.sleepUntil = -1; debug("notifying listeners"); this.mgr.notifyListeners(); } // if } catch(InterruptedException e) { debug("I'm interrupted"); } } debug("I'm stopping"); } }