647 lines · 20.6 KB · Java
RawDownload
    }     /*     * Inserts the timer back into the queue.  This method     * is used by a callback thread after it has called the     * timer owner's tick() method.  This method recomputes     * the sleepUntil field.     * Assumes the caller has the TimerThread and Timer monitor.     */    protected static void requeue(Timer timer) {        if (!timer.stopped) {            long now = System.currentTimeMillis();            if (timer.regular) {                timer.sleepUntil += timer.interval;            } else {                timer.sleepUntil = now + timer.interval;            }            enqueue(timer);        } else if (debug) {            System.out.println(Thread.currentThread().getName()                + ": requeue " + timer.interval + ": no-op");        }    }} /* This class implements a simple thread whose only purpose is to call atimer owner's tick() method.  A small fixed-sized pool of threads ismaintained and is protected by the class monitor.  If the pool isexhausted, a new thread is temporarily created and destroyed whendone. A thread that's in the pool waits on it's own monitor.  When thethread is retrieved from the pool, the retriever notifies the thread'smonitor. */ class TimerTickThread extends Thread {    /*     * Maximum size of the thread pool.     */    static final int MAX_POOL_SIZE = 3;     /*     * Number of threads in the pool.     */    static int curPoolSize = 0;     /*     * The pool of timer threads.     */    static TimerTickThread pool = null;     /*     * Is used when linked into the thread pool.     */    TimerTickThread next = null;     /*     * This is the handle to the timer whose owner's     * tick() method will be called.     */    Timer timer;     /*     * The value of a timer's sleepUntil value is captured here.     * This is used to determine whether or not the timer should     * be reinserted into the queue.  If the timer's sleepUntil     * value has changed, the timer is not reinserted.     */    long lastSleepUntil;     /*     * Creates a new callback thread to call the timer owner's     * tick() method.  A thread is taken from the pool if one     * is available, otherwise, a new thread is created.     * The thread handle is returned.     */    protected static synchronized TimerTickThread call(            Timer timer, long sleepUntil) {        TimerTickThread thread = pool;         if (thread == null) {            // create one.            thread = new TimerTickThread();            thread.timer = timer;            thread.lastSleepUntil = sleepUntil;            thread.start();        } else {            pool = pool.next;            thread.timer = timer;            thread.lastSleepUntil = sleepUntil;            synchronized (thread) {                thread.notify();            }        }        return thread;    }     /*     * Returns false if the thread should simply exit;     * otherwise the thread is returned the pool, where     * it waits to be notified.  (I did try to use the     * class monitor but the time between the notify     * and breaking out of the wait seemed to take     * significantly longer; need to look into this later.)     */    private boolean returnToPool() {        synchronized (getClass()) {            if (curPoolSize >= MAX_POOL_SIZE) {                return false;            }            next = pool;            pool = this;            curPoolSize++;            timer = null;        }        while (timer == null) {            synchronized (this) {                try {                    wait();                } catch (InterruptedException ex) {                   // Just drop through and retest timer.                }            }        }        synchronized (getClass()) {            curPoolSize--;        }        return true;    }     public void run() {        do {            timer.owner.tick(timer);            synchronized (TimerThread.timerThread) {                synchronized (timer) {                    if (lastSleepUntil == timer.sleepUntil) {                        TimerThread.requeue(timer);                    }                }            }        } while (returnToPool());    }}

Lines 501–647 of 647. Previous lines