Goal Oriented Scheduling for Java
What is Gos4j?
Gos4j is a way of organising processing priorities based on goals.
Each goal is processed based on its time to complete, and its progress towards that goal.
Deadlines are used to act as the target completion time for a goal,
and can be expressed in either relative or absolute terms.
What do I use it for?
You should use Gos4j wherever you have a requirement to support
an unknown processing environment with real time constraints.
A typical example of this would be in an application programming set-up,
where user code would run alongside your code,
and so fixed priority scheduling may not be efficient.
The reason why Gos4j is so good in these environments is that
it can easily reschedule threads to meet as many of the specified constraints as possible.
So when the going gets tough,
overall performance will degrade gracefully
and conflicting time constraints will be handled equitably.
What is wrong with using setPriority(...)?
Developers use the setPriority(...) method call for two broad reasons:
Using the method to ensure a sequence of execution is risky.
This is because the way in which the OS/VM handles threads can vary,
and it is far better to use a latching wait() notify() instead.
- to ensure a sequence of execution.
- to prevent background tasks from delaying key processing.
The more common usage is to prevent background tasks from delaying key processing.
This works fine when there are only a small number of threads to manage in this manner.
The problems come when the processing gets heavy.
Commonly at peak processing the background threads will never execute.
And if you have many high priority (or low priority) threads then there are only so many priority
levels you can use to schedule them;
this problem grows exponentially.
Gos4j gets around these problems by changing the priority levels according to the goals specified.
So that if a background task gets locked out by short term goals in another thread
then the scheduler will elevate the priority of the background task
(when it can - i.e. during short luls) to meet all the deadlines.
How do I use it?
- Read and understand the license.
- Download the two Java jar files from here.
- Optionally download the documentation zip file from here.
- Place the two jar files in your Java classpath.
- Add the appropriate calls to the API to your own code.
How do I say how long each goal should take?
You should specify goals at the user's level,
a web server might require page delivery within 4 seconds of the HTTP request,
a data persister may require to complete a persistence cycle every minute,
and a button press should provide visual feedback within 500ms.
To do this you can specify goal deadlines as either a relative duration (from start)
or as an absolute time.
I still want to set some of my own priorities, how can I do this?
The Gos4j scheduler works within a band of priorities.
This band is defined in the Gos4jConfig and can be adjusted as required.
The default band uses all the priorities between (but not including)
the MAX_PRIORITY and MIN_PRIORITY levels.
Furthermore the scheduler only temporarily adjusts the priority of the threads it touches.
This means that once no goals are in progress using a particular thread then that thread
will be returned to its original priority.
Will my program work faster?
It's not magic - it does not make your code run any faster under normal circumstances.
What it will do is allow your program to remain as near to being functionally correct
under conditions of stress.
If you need your code to run faster then there are much better ways
- faster VM, faster OS and most importantly better written code.
What is the Gos4j footprint?
Gos4j adds only a few Kb to your installation,
a few more Kb to the runtime memory usage,
a small ammount of extra processing for each goal update
and a degree of extra thread switching caused by the dynamic prioritisation.
It adds one more thread to your system.
The exact footprint depends on the version you are using.
How do I pass the Goal object around my program?
I don't want to add parameters everywhere!
The best method of using Goal objects in various parts of your program
is basically dependant on the type of environment your code runs in.
The simplest way is to add the Goal object as an attribute of the business object
you are using to embody the task at hand.
In a servlet environment you can have the Goal and GoalType objects
held in the session environment.
Alternatively you can use thread local variables to hold the current Goal.