|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectsim.engine.Schedule
public class Schedule
Schedule defines a threadsafe scheduling queue in which events can be scheduled to occur at future time. The time of the most recent event which has already occured is given by the getTime() method. If the current time is BEFORE_SIMULATION (defined to be EPOCH - 1), then the schedule is set to the "time before time" (the schedule hasn't started running yet). If the current time is AFTER_SIMULATION (positive infinity), then the schedule has run out of time. EPOCH (0.0) is defined as the first timestep for which you can legally schedule a value. EPOCH_PLUS_ESPILON is defined as the smallest possible second timestep for which you can legally sechedule a value. If you're scheduling events to occur on integer timesteps, you may want to ensure that your simulation does not run beyond MAXIMUM_INTEGER (9007199254740992L or 9.007199254740992E15). For values of a double d >= MAXIMUM_INTEGER, d + 1 == d !
An event is defined as a Steppable object. You can schedule events to either occur a single time or to occur repeatedly at some interval. If the event occurs repeatedly, the schedule will provide you with a Stoppable object on which you can call stop() to cancel all future repeats of the event. If instead you wish to "stop" a single-time event from occuring before its time has come, you should do so through the use of a TentativeStep object. At present you cannot delete objects from the Schedule -- just stop them and let them drop out in due course.
The schedule is pulsed by calling its step(...) method. Each pulse, the schedule finds the minimum time at which events are scheduled, moves ahead to that time, and then calls all the events scheduled at that time. Multiple events may be scheduled for the same time. No event may be scheduled for a time earlier than getTime(). If at time getTime() you schedule a new event for time getTime(), then actually this event will occur at time getTime()+epsilon, that is, the smallest possible slice of time greater than getTime().
Events at a step are further subdivided and scheduled according to their ordering, an integer. Objects for scheduled for lower orderings for a given time will be executed before objects with higher orderings for the same time. If objects are scheduled for the same time and have the same ordering value, their execution will be randomly ordered with respect to one another unless (in the very rare case) you have called setShuffling(false);. Generally speaking, most experiments with good model methodologies will want random shuffling left on, and if you need an explicit ordering, it may be better to rely on Steppable's orderings or to use a Sequence.
You might be wondering: why bother with using orderings? After all, can't you achieve the same thing by just stretching elements out in time? There are two reasons to use orderings. First, it allows you to use the getTime() method to keep tabs on the current time in a way that might be convenient to you. But second and more importantly, MASON's GUI facility will update its displays and inspectors only after all Steppables scheduled for a given timestamp have completed, and so orderings give you a way of subdividing the interval of time between GUI updates.
You can clear out the entire Schedule by calling reset(), including about-to-be executed Steppables in the current timestep. However, this does not prevent AsynchronousSteppables from suddenly rescheduling themselves in the queue. Stopping the simulation from within a Steppable object's step() method is best done by calling SimState.kill(). From the main thread, the most straightforward way to stop a simulation is to just stop calling schedule.step(...), and proceed directly to SimState.finish().
You can get the number of times that step(...) has been called on the schedule by calling the getSteps() method. This value is incremented just as the Schedule exits its step(...) method and only if the method returned true. Additionally, you can get a string version of the current time with the getTimestamp(...) method.
Note on Synchronization. In order to maximize the ability for threads to access the Schedule at any time, Schedule uses two locks for synchronization. First, the step() method synchronizes on the Schedule itself. This prevents step() from being called simultaneously from different threads; also step() tests to make sure that it's not called reentrantly from within the same thread. Second, many methods synchronize on an internal lock, including step(). This allows step() to synchronize on the lock only to suck out the relevant Steppables from the Heap and to advance the timestep; all other portions of step() are outside of the lock. Thus when step() actually steps the Steppables, even in different threads (like AsynchronousSteppable or ParallelSequence), they can turn around and submit step-requests to the Schedule even while it's still in its step() method.
One downside to this flexibility is that it's very inefficient to check, at each step of a Steppable, whether the Schedule has been reset or not. Thus now if you call reset() or [better] SimState.kill(), the Schedule will continue to step Steppables until it has exhausted ones scheduled for the current timestep. Only at that point will it cease.
Heaps and Calendar Queues. Schedule uses a plain-old binary heap for its queueing mechanism. This is reasonably efficient, but it could be made more efficient with a Calendar Queue designed for the purposes of your simulation. We settled on a Heap because we do not know what the expected scheduling pattern will be for any given simulation, and so had to go for the most general case. If you'd care to customize your queue, you can do so by overriding the createHeap() method in a custom Schedule. We imagine this would be rare.
Nested Class Summary | |
---|---|
static class |
Schedule.Key
Timestamps stored as keys in the heap. |
Field Summary | |
---|---|
static double |
AFTER_SIMULATION
The time which indicates that the Schedule is finished. |
static double |
BEFORE_SIMULATION
The time which indicates that the Schedule hasn't started yet. |
static double |
EPOCH
The first possible schedulable time. |
static double |
EPOCH_PLUS_EPSILON
The second possible schedulable time. |
protected java.lang.Object |
lock
|
static double |
MAXIMUM_INTEGER
The last time beyond which the schedule is no longer able to precisely maintain integer values due to loss of precision. |
Constructor Summary | |
---|---|
Schedule()
Creates a Schedule. |
Method Summary | |
---|---|
protected Heap |
createHeap()
Returns a Heap to be used by the Schedule. |
long |
getSteps()
Returns the number of steps the Schedule has pulsed so far. |
double |
getTime()
Same as getTime() -- returns the current timestep |
java.lang.String |
getTimestamp(double time,
java.lang.String beforeSimulationString,
java.lang.String afterSimulationString)
Returns a given time in string format. |
java.lang.String |
getTimestamp(java.lang.String beforeSimulationString,
java.lang.String afterSimulationString)
Returns the current time in string format. |
boolean |
isShuffling()
Returns true (the default) if the Steppables' order is randomly shuffled when they have identical orderings and are scheduled for the same time; else returns false, indicating that Steppables with identical orderings will be executed in the order in which they were inserted into the schedule. |
void |
reset()
Empties out the schedule and resets it to a pristine state BEFORE_SIMULATION, with steps = 0. |
boolean |
scheduleComplete()
Returns true if the schedule has nothing left to do. |
boolean |
scheduleOnce(double time,
int ordering,
Steppable event)
Schedules the event to occur at the provided time, and in the ordering provided. |
boolean |
scheduleOnce(double time,
Steppable event)
Schedules the event to occur at the provided time, 0 ordering. |
boolean |
scheduleOnce(Schedule.Key key,
Steppable event)
Schedules an item. |
boolean |
scheduleOnce(Steppable event)
Schedules the event to occur at getTime() + 1.0, 0 ordering. |
boolean |
scheduleOnce(Steppable event,
int ordering)
Schedules the event to occur at getTime() + 1.0, and in the ordering provided. |
boolean |
scheduleOnceIn(double delta,
Steppable event)
Schedules the event to occur at getTime() + delta, 0 ordering. |
boolean |
scheduleOnceIn(double delta,
Steppable event,
int ordering)
Schedules the event to occur at getTime() + delta, and in the ordering provided. |
Stoppable |
scheduleRepeating(double time,
int ordering,
Steppable event)
Schedules the event to recur at an interval of 1.0 starting at the provided time, and in the ordering provided. |
Stoppable |
scheduleRepeating(double time,
int ordering,
Steppable event,
double interval)
Schedules the event to recur at the specified interval starting at the provided time, and in the ordering provided. |
Stoppable |
scheduleRepeating(double time,
Steppable event)
Schedules the event to recur at the specified interval starting at the provided time, and at 0 ordering. |
Stoppable |
scheduleRepeating(double time,
Steppable event,
double interval)
Schedules the event to recur at the specified interval starting at the provided time, in ordering 0. |
Stoppable |
scheduleRepeating(Steppable event)
Schedules the event to recur at an interval of 1.0 starting at getTime() + 1.0, and at 0 ordering. |
Stoppable |
scheduleRepeating(Steppable event,
double interval)
Schedules the event to recur at the specified interval starting at getTime() + interval, and at 0 ordering. |
Stoppable |
scheduleRepeating(Steppable event,
int ordering,
double interval)
Schedules the event to recur at the specified interval starting at getTime() + interval, and at the provided ordering. |
void |
setShuffling(boolean val)
Sets the schedule to randomly shuffle the order of Steppables (the default), or to not do so, when they have identical orderings and are scheduled for the same time. |
boolean |
step(SimState state)
Steps the schedule, gathering and ordering all the items to step on the next time step (skipping blank time steps), and then stepping all of them in the decided order. |
double |
time()
Returns the current timestep |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public static final double EPOCH
public static final double BEFORE_SIMULATION
public static final double AFTER_SIMULATION
public static final double EPOCH_PLUS_EPSILON
public static final double MAXIMUM_INTEGER
protected java.lang.Object lock
Constructor Detail |
---|
public Schedule()
Method Detail |
---|
protected Heap createHeap()
public void setShuffling(boolean val)
public boolean isShuffling()
public double time()
public double getTime()
public java.lang.String getTimestamp(java.lang.String beforeSimulationString, java.lang.String afterSimulationString)
public java.lang.String getTimestamp(double time, java.lang.String beforeSimulationString, java.lang.String afterSimulationString)
public long getSteps()
public void reset()
public boolean scheduleComplete()
public boolean step(SimState state)
public boolean scheduleOnce(Steppable event)
public boolean scheduleOnceIn(double delta, Steppable event)
public boolean scheduleOnce(Steppable event, int ordering)
public boolean scheduleOnceIn(double delta, Steppable event, int ordering)
public boolean scheduleOnce(double time, Steppable event)
public boolean scheduleOnce(double time, int ordering, Steppable event)
public boolean scheduleOnce(Schedule.Key key, Steppable event)
public Stoppable scheduleRepeating(Steppable event)
Note that calling stop() on the Stoppable will not only stop the repeating, but will also make the Schedule completely forget (lose the pointer to) the Steppable scheduled here. This is particularly useful if you need to make the Schedule NOT serialize certain Steppable objects.
public Stoppable scheduleRepeating(Steppable event, double interval)
Note that calling stop() on the Stoppable will not only stop the repeating, but will also make the Schedule completely forget (lose the pointer to) the Steppable scheduled here. This is particularly useful if you need to make the Schedule NOT serialize certain Steppable objects.
public Stoppable scheduleRepeating(Steppable event, int ordering, double interval)
Note that calling stop() on the Stoppable will not only stop the repeating, but will also make the Schedule completely forget (lose the pointer to) the Steppable scheduled here. This is particularly useful if you need to make the Schedule NOT serialize certain Steppable objects.
public Stoppable scheduleRepeating(double time, Steppable event)
Note that calling stop() on the Stoppable will not only stop the repeating, but will also make the Schedule completely forget (lose the pointer to) the Steppable scheduled here. This is particularly useful if you need to make the Schedule NOT serialize certain Steppable objects.
public Stoppable scheduleRepeating(double time, Steppable event, double interval)
Note that calling stop() on the Stoppable will not only stop the repeating, but will also make the Schedule completely forget (lose the pointer to) the Steppable scheduled here. This is particularly useful if you need to make the Schedule NOT serialize certain Steppable objects.
public Stoppable scheduleRepeating(double time, int ordering, Steppable event)
Note that calling stop() on the Stoppable will not only stop the repeating, but will also make the Schedule completely forget (lose the pointer to) the Steppable scheduled here. This is particularly useful if you need to make the Schedule NOT serialize certain Steppable objects.
public Stoppable scheduleRepeating(double time, int ordering, Steppable event, double interval)
Note that calling stop() on the Stoppable will not only stop the repeating, but will also make the Schedule completely forget (lose the pointer to) the Steppable scheduled here. This is particularly useful if you need to make the Schedule NOT serialize certain Steppable objects.
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |