FileDocCategorySizeDatePackage
TimerQueue.javaAPI DocJava SE 6 API7390Tue Jun 10 00:26:42 BST 2008javax.swing

TimerQueue

public class TimerQueue extends Object implements Runnable
Internal class to manage all Timers using one thread. TimerQueue manages a queue of Timers. The Timers are chained together in a linked list sorted by the order in which they will expire.
version
1.39 07/11/06
author
Dave Moore

Fields Summary
private static final Object
sharedInstanceKey
private static final Object
expiredTimersKey
Timer
firstTimer
boolean
running
private static final Object
classLock
Constructors Summary
public TimerQueue()
Constructor for TimerQueue.



            
      
        super();

        // Now start the TimerQueue thread.
        start();
    
Methods Summary
synchronized voidaddTimer(javax.swing.Timer timer, long expirationTime)

        Timer previousTimer;
        Timer nextTimer;

        // If the Timer is already in the queue, then ignore the add.
        if (timer.running) {
            return;
        }

        previousTimer = null;
        nextTimer = firstTimer;

        // Insert the Timer into the linked list in the order they will
        // expire.  If two timers expire at the same time, put the newer entry
        // later so they expire in the order they came in.

        while (nextTimer != null) {
            if (nextTimer.expirationTime > expirationTime) break;

            previousTimer = nextTimer;
            nextTimer = nextTimer.nextTimer;
        }

        if (previousTimer == null) {
            firstTimer = timer;
        }
        else {
            previousTimer.nextTimer = timer;
        }

        timer.expirationTime = expirationTime;
        timer.nextTimer = nextTimer;
        timer.running = true;
        notify();
    
synchronized booleancontainsTimer(javax.swing.Timer timer)

        return timer.running;
    
synchronized longpostExpiredTimers()
If there are a ton of timers, this method may never return. It loops checking to see if the head of the Timer list has expired. If it has, it posts the Timer and reschedules it if necessary.

        Timer   timer;
        long    currentTime;
        long    timeToWait;

        // The timeToWait we return should never be negative and only be zero
        // when we have no Timers to wait for.

        do {
            timer = firstTimer;
            if (timer == null) return 0;

            currentTime = System.currentTimeMillis();
            timeToWait = timer.expirationTime - currentTime;

            if (timeToWait <= 0) {
                try {
                    timer.post();  // have timer post an event
                }
                catch (SecurityException e) {
                }

                // Remove the timer from the queue
                removeTimer(timer);

                // This tries to keep the interval uniform at
                // the cost of drift.
                if (timer.isRepeats()) {
                    addTimer(timer, currentTime + timer.getDelay());
                }

                // Allow other threads to call addTimer() and removeTimer()
                // even when we are posting Timers like mad.  Since the wait()
                // releases the lock, be sure not to maintain any state
                // between iterations of the loop.

                try {
                    wait(1);
                }
                catch (InterruptedException e) {
                }
            }
        } while (timeToWait <= 0);

        return timeToWait;
    
synchronized voidremoveTimer(javax.swing.Timer timer)

        Timer   previousTimer;
        Timer   nextTimer;
        boolean found;

        if (!timer.running) return;

        previousTimer = null;
        nextTimer = firstTimer;
        found = false;

        while (nextTimer != null) {
            if (nextTimer == timer) {
                found = true;
                break;
            }

            previousTimer = nextTimer;
            nextTimer = nextTimer.nextTimer;
        }

        if (!found) return;

        if (previousTimer == null) {
            firstTimer = timer.nextTimer;
        }
        else {
            previousTimer.nextTimer = timer.nextTimer;
        }

        timer.expirationTime = 0;
        timer.nextTimer = null;
        timer.running = false;
    
public synchronized voidrun()

        long timeToWait;

        try {
            while (running) {
                timeToWait = postExpiredTimers();
                try {
                    wait(timeToWait);
                }
                catch (InterruptedException e) {
                }
            }
        }
        catch (ThreadDeath td) {
            running = false;
            // Mark all the timers we contain as not being queued.
            Timer timer = firstTimer;
            while (timer != null) {
                timer.cancelEvent();
                timer = timer.nextTimer;
            }
            SystemEventQueueUtilities.restartTimerQueueThread();
            throw td;
        }
    
public static javax.swing.TimerQueuesharedInstance()

        synchronized (classLock) {
            TimerQueue sharedInst = (TimerQueue)
                                    SwingUtilities.appContextGet(
                                                        sharedInstanceKey);
            if (sharedInst == null) {
                sharedInst = new TimerQueue();
                SwingUtilities.appContextPut(sharedInstanceKey, sharedInst);
            }
            return sharedInst;
        }
    
synchronized voidstart()

        if (running) {
            throw new RuntimeException("Can't start a TimerQueue " +
                                       "that is already running");
        }
        else {
            final ThreadGroup threadGroup = 
                AppContext.getAppContext().getThreadGroup();
            java.security.AccessController.doPrivileged(
                new java.security.PrivilegedAction() {
                public Object run() {
                    Thread timerThread = new Thread(threadGroup, TimerQueue.this,
                                                    "TimerQueue");
                    timerThread.setDaemon(true);
                    timerThread.setPriority(Thread.NORM_PRIORITY);
                    timerThread.start();
                    return null;
                }
            });
            running = true;
        }
    
synchronized voidstop()

        running = false;
        notify();
    
public synchronized java.lang.StringtoString()

        StringBuffer buf;
        Timer nextTimer;

        buf = new StringBuffer();
        buf.append("TimerQueue (");

        nextTimer = firstTimer;
        while (nextTimer != null) {
            buf.append(nextTimer.toString());

            nextTimer = nextTimer.nextTimer;
            if (nextTimer != null) buf.append(", ");
        }

        buf.append(")");
        return buf.toString();