Scheduler

Origin: Lea 97
Reason: To implement a general purpose thread scheduling policy.
Synopsis: Use two classes: a general Scheduler, which assign a resource to a thread, and a specialized ScheduleOrdering, which selects one thread among many to execute.
Example: Entries to log are queued while waiting to be printed. Queueing minimizes the chance of printing entries in the wrong termporal order.
Solution:
Request This class implements SchedulingOrdering. Objects encapsulate a request for a Processor
Processor This class performs the computation abstracted by a Request. It asks the Scheduler the ok to process. It informs the scheduler when the process is completed.
Scheduler This class schedules Requests to the Processor. It relies on interface ScheduleOrdering, implemented by each Request, for the ordering.
ScheduleOrdering Interface used to decide the order in which Requests a processed. Keeps the Scheduler independend of the details of a Request.
See also: ReadWriteLock (is a specialized form of Scheduler)
Note: In its simplest form, the key method of Processor looks like:
void process (Request r) {
    scheduler.enter (r);
    ... // process this request
    scheduler.done ();
}
The Scheduler defines a variable shared by its enter and done methods
Thread runningThread;
The Scheduler's enter method looks like:
void enter (Request r) {
    Thread thisThread = Thread.currentThread ();
    synchronized (this) {
        if (runningThread == null) {    // processor is free
            runningThread = thisThread;
            return;
        }
        ... // place thisThread in a waiting list;
    }
    synchronized (thisThread) {
        while (thisThread != runningThread)
            thisThread.wait();
    }
    synchronized (this) {
        remove thisThread from the waiting list;
    }
}
The Scheduler's done method looks like:
void done () {
    synchronized (this) {
        if (there are no waiting threads) {
            runningThread = null;
            return;
        }
        runningThread = first thread in waiting list;
    }
    synchronized (runningThread) {
        runningThread.notifyAll ();
    }
}