Class Scheduler

  • All Implemented Interfaces:
    java.io.Serializable

    public final class Scheduler
    extends java.lang.Object
    implements java.io.Serializable
    This class is for scheduling the non-preemptive execution of tasks. The class creates a single thread, and will independently manange and run its loaded objects. The Scheduler accepts objects for scheduling, at any time during its existence. The scheduled object must implement no-arg, void slice() method, to be used as a time slice, in which to perform some fixed piece of functionality. The scheduler will provide the calling mechanism. An objectwith this type of method implementation will be considered a task for the purposes of this class.

    The scheduler's purpose is to provide an exclusive thread of execution amongst the scheduled tasks. It will assure that only one of the tasks is running at any given time, therefore shared memory between the tasks cannot be corrupted by the scheduler due to synchronization problems.

    All scheduler methods are properly synchronized, to allow task loading, unloading, and management, from other threads, as well as by the scheduled tasks themselves.

    Up to 32 tasks can be loaded, at any given time, for scheduling. Once loaded, tasks can be scheduled to run in any, or all, of three ways; Synchronous, Triggered, or Asynchronous. The class implements three methods to flag a loaded task as such. The following is a description of the scheduling algorithm:

    When a task is flagged as asynchronous, it will be run only when no tasks are flagged as synchronous, or triggered, at the start of its slice. Its asynchronous flag is not cleared when it is run, meaning until stopped, it will be run again automatically, as scheduling permits. Scheduling among multiple asynchronous flags is round-robbin, to ensure each an opportunity to run. This provides a method for scheduling low-priority tasks. Typically an asynchronous task will break its functionality into distinct pieces, and use a switch() type mechanism to execute only one piece per timeslice.

    When a task is flagged as triggered, will run before any tasks flagged asynchronous, but only when no tasks are flagged as synchronous, at the start of its slice. The trigger flag is cleared when the task is run, meaning that unless re-flagged as triggered, it will not run again through the trigger scheduling algorithm. This provides an event-driven mode of execution, but at a lower priority than the synchronous mode.

    When a task is flagged as synchronous, it will run before any triggered, or asynchronous flagged tasks are allowed to run. Its synchronous flag is also cleared when the task is run. Since the scheduling is not preemptive, any currently running task is allowed to complete. This flag provides the highest responsiveness to a synchronizing event.

    The stop method is used to prevent the execution of any flagged task. General notes:

    • Since scheduling is not preemptive, developers must agressively minimize asynchronous task's run time length, to decrease the latency of event responsiveness. This becomes especially important when tasks are elevated in priority.
    • Non-preemptive scheduling eliminates all synchronization concerns for objects shared between scheduled tasks.
    • As a general rule: try to use asynchronous scheduling initially. Then, as the design runtime load increases, selected tasks can be boosted in proiority to achieve the desired responsiveness.

    Note: This class supports serialisation. It will restart the scheduling task automatically on deserialisation. However, in order for serialisation to succeed, all of the loaded tasks must also be serialisable.

    Version:
    1.0, 01-Nov-99 Initial release
    See Also:
    Serialized Form
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private static java.lang.String INDEX_INVALID  
      private java.lang.Runnable kernel  
      private java.lang.Object[] list  
      private int soonFlags  
      private int syncFlags  
      private java.lang.Thread thread  
      private int wakeFlags  
    • Constructor Summary

      Constructors 
      Constructor Description
      Scheduler()
      Nothing is performed in the constructor, since no tasks can be scheduled for execution until they have been loaded.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void drop​(int task)
      This method clears all scheduling flags for the indicated task, and also removes it from the table.
      int load​(java.lang.Object task)
      This method accepts a task to be scheduled.
      boolean pending()
      The purpose of this function is to reduce event-driven task latency by allowing asynchronous tasks to voluntarily exit prematurely.
      private void readObject​(java.io.ObjectInputStream in)  
      boolean setEnabled​(boolean enabled)
      This method will start, or suspend, the scheduler.
      boolean soon​(int task)
      This method sets the triggered execution flag for a task.
      void stop​(int task)
      This method clears all scheduling flags for indicated task.
      boolean sync​(int task)
      This method sets the synchronous execution flag for a task.
      boolean wake​(int task)
      This method sets the asynchronous execution flag for a task.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • thread

        private transient java.lang.Thread thread
      • syncFlags

        private int syncFlags
      • soonFlags

        private int soonFlags
      • wakeFlags

        private int wakeFlags
      • list

        private java.lang.Object[] list
      • kernel

        private final java.lang.Runnable kernel
    • Constructor Detail

      • Scheduler

        public Scheduler()
        Nothing is performed in the constructor, since no tasks can be scheduled for execution until they have been loaded.
    • Method Detail

      • readObject

        private void readObject​(java.io.ObjectInputStream in)
                         throws java.io.IOException,
                                java.lang.ClassNotFoundException
        Throws:
        java.io.IOException
        java.lang.ClassNotFoundException
      • setEnabled

        public boolean setEnabled​(boolean enabled)
        This method will start, or suspend, the scheduler. The scheduler will be started automatically when the first task is flagged for execution. The method is idempotent; therefore enabling an already enabled scheduler will cause no effect, just as disabling a currently disabled scheduler.
        Parameters:
        enabled - The flag to indicate if this is a startup, or suspend operation.
        Returns:
        true if successfully started or stopped, false if not for logical reasons, i.e. already stopped/started, no tasks running.
      • load

        public int load​(java.lang.Object task)
        This method accepts a task to be scheduled. If the task is accepted, it is placed in the table, but will not be executed, until it is flagged for operation. If the execution of the task slice results in an exception, the task will be automatically dropped from the queue.
        Parameters:
        task - The task to attempt to schedule, it may be either local, remote, or even a proxy, when enabled.
        Returns:
        the index of the task in the table. The task table index is used in the scheduling methods.
        Throws:
        java.lang.IllegalArgumentException - If the task table is full.
      • sync

        public boolean sync​(int task)
        This method sets the synchronous execution flag for a task. The flag will be cleared automatically, when the scheduler calls this task.
        Parameters:
        task - The index of the task in the table
        Returns:
        false if the task was already flagged, or not in the queue, else true if successfully flagged.
        Throws:
        java.lang.IllegalArgumentException - If the task table index is invalid.
      • soon

        public boolean soon​(int task)
        This method sets the triggered execution flag for a task. It will be cleared just before passing execution on to the task.
        Parameters:
        task - The index of the task in the table
        Returns:
        true if successfully flagged, false if already flagged
        Throws:
        java.lang.IllegalArgumentException - If the task table index is invalid.
      • wake

        public boolean wake​(int task)
        This method sets the asynchronous execution flag for a task. It will not be cleared when passing execution on to the task. The flag will retain its state, until disabled through the stop method.
        Parameters:
        task - The index of the task to be scheduled for continuous asynchronous execution.
        Returns:
        true if successfully flagged, false if already flagged.
        Throws:
        java.lang.IllegalArgumentException - If the task table index is invalid.
      • stop

        public void stop​(int task)
        This method clears all scheduling flags for indicated task. The task will reamain in the table however. Note: to remove a task, use the drop method instead, it automatically calls stop, before removing the task from the table.
        Parameters:
        task - The index of the task in the table
        Throws:
        java.lang.IllegalArgumentException - If the task table index is invalid.
      • drop

        public void drop​(int task)
        This method clears all scheduling flags for the indicated task, and also removes it from the table.
        Parameters:
        task - The index of the task to stop and remove from the table.
        Throws:
        java.lang.IllegalArgumentException - If the task table index is invalid.
      • pending

        public boolean pending()
        The purpose of this function is to reduce event-driven task latency by allowing asynchronous tasks to voluntarily exit prematurely. To improve responsiveness, asynchronous tasks could check this method, before going on to another functionally distinct section of its task execution. It is normally checked when the async task has some periodic extra work, if the method returns false, the extra work could be processed in its current slice.
        Returns:
        true if synchronous or triggered tasks have been flagged for execution, false if it is OK for the task to continue running a little longer.