FileDocCategorySizeDatePackage
Scheduler.javaAPI DocphoneME MR2 API (J2ME)6924Wed May 02 18:00:34 BST 2007com.sun.perseus.util

Scheduler

public final class Scheduler extends Object
This class is used to multiplex Runnables that need to be run at a fixed rate.
version
$Id: Scheduler.java,v 1.3 2006/04/21 06:35:54 st125089 Exp $

Fields Summary
RunnableQueue
rq
The associated RunnableQueue.
Entry[]
entries
The current list of Runnables scheduled at a fixed interval.
Constructors Summary
Scheduler(RunnableQueue rq)
Builds a new Scheduler for the given RunnableQueue.

param
rq the associated RunnableQueue. Should not be null.


                          
       
        if (rq == null) {
            throw new NullPointerException();
        }

        this.rq = rq;
    
Methods Summary
public synchronized voidadd(java.lang.Runnable r, long interval, com.sun.perseus.util.RunnableQueue.RunnableHandler handler)
Adds a new Runnable to be run at the requested fixed interval. Note that if the input Runnable is entered multiple times into the scheduler, it will be run once for each interval it is registered with.

param
r the Runnable to run at a fixed rate. Should not be null.
param
interal the interval, in milliseconds, between runs of the Runnable. Should be strictly positive.
param
handler the associated RunHandler, which should be notified when the Runnable is actually run. May be null.

        if (r == null || interval <= 0) {
            throw new IllegalArgumentException();
        }

        Entry[] tmpEntries = new Entry[entries.length + 1];
        System.arraycopy(entries, 0, tmpEntries, 0, entries.length);
        Entry newEntry = new Entry();
        newEntry.runnable = r;
        newEntry.interval = interval;
        newEntry.handler = handler;
        tmpEntries[entries.length] = newEntry;
        
        entries = tmpEntries;
    
public synchronized longnextRun(long currentTime)

param
currentTime the current time, in milliseconds.
return
the time until the next scheduled Runnable needs to be run. Returns -1 if there is no scheduled Runnable.

        if (entries.length > 0) {
            long nextRun = entries[0].nextRun;
            for (int i = 1; i < entries.length; i++) {
                if (entries[i].nextRun < nextRun) {
                    nextRun = entries[i].nextRun;
                }
            }

            nextRun -= currentTime;
            if (nextRun < 0) {
                nextRun = 0;
            }

            return nextRun;
        } else {
            return -1;
        }
    
public synchronized voidremove(java.lang.Runnable r)
Removes a Runnable from the list of Runnables that are scheduled at a fixed interval. If the Runnable was registered multiple times with this scheduler, all instances are removed.

param
r the Runnable to removed from the list of Runnables scheduled at a fixed rate.

        while (removeImpl(r)) {}
    
private booleanremoveImpl(java.lang.Runnable r)
Implementation helper. Removes the input Runnable, and returns true if the Runnable was found.

param
r the Runnable to remove.
return
true if the Runnable was found.

        // First, look for the given entry.
        int i = entries.length + 1;
        for (i = 0; i < entries.length; i++) {
            if (entries[i].runnable == r) {
                break;
            }
        }
        
        if (i < entries.length) {
            // We did find the entry.
            Entry[] tmpEntries = new Entry[entries.length - 1];
            System.arraycopy(entries, 0, tmpEntries, 0, i);
            System.arraycopy(entries, i + 1, tmpEntries, i, entries.length - 1 - i);

            // Mark the entry to be removed as dead, so that it does not get
            // run in the run method, in case a Runnable removes itself during
            // the scheduler's run method.
            entries[i].live = false;

            entries = tmpEntries;            
            return true;
        }

        return false;
    
public synchronized voidrun(long currentTime)
Runs the scheduled Runnables that are due or overdue.

param
currentTime the currentTime when this runnable is ran.

        // We need to keep a local reference to entries in case
        // a Runnable unschedules during its run() method.
        Entry[] lEntries = entries;
        for (int i = 0; i < lEntries.length; i++) {
            if (lEntries[i].nextRun <= currentTime && lEntries[i].live) {
                lEntries[i].runnable.run();
                lEntries[i].handler.runnableInvoked(rq, lEntries[i].runnable);
                lEntries[i].nextRun = currentTime + lEntries[i].interval;
            }
        }