Java threads are most difficult to control. What if a thread gets stuck in a blocking method? What if something is
wrong and the thread doesn't get CPU time? What if there is a bug? There are
lots of 'what if'' situations. See for example the Shadow.
Tymeac is a superb implementation of a very simple concept:
Put requests in queues for processing by
asynchronous threads.
In a nutshell, Tymeac comprises queues with each queue having its own
pool of threads. However, Tymeac Queue Threads are not your traditional pool
threads. Every Queue Thread has its own
management structure. Each
event in the life of a Queue Thread is timed.
Although there is no way to stop a thread, Tymeac handles the run-a-way or
blocking-forever thread problems as best as can be handled at the
application level.
Interrupt
Thread "interrupt()" is a disaster. The original developers probably had
a vision that programmers would want to interrupt an executing thread. But
they never perfected that vision. What we have now are threads interrupting
themselves as well as other threads sometimes with erroneous results.
Lets say you create thread “A” and you expect that thread to complete
some work within a time limit.
- You execute a timed wait for thread “A”.
- Thread “A” does not complete within the time limit,
- the time expires and
- you regain control.
- Your code continues with other work.
- Then you have a second timed wait for another thread “B”.
- If thread “A” then issues interrupt(), it interrupts the caller at
the second wait.
This can easily happen with packages you buy and cannot alter,
especially message-writer methods. It is common practice to make a
message-writer a separate thread so it doesn’t affect the main thread if
it hangs or causes an exception.
If you have a multi-thread environment (i.e. thread “C”, “D” etc.),
then using interrupt() only exacerbates the problem.
interrupt() is like getting kicked in the butt – you know you’ve been
kicked but you don’t know who did it, when or why.
Tymeac does not use "interrupt()". All communication with Queue Threads
is done through the thread's management structure.
NotifyAll
Both
NotifyAll() and SignalAll() are shot gun methods. Having multiple threads
waiting on a single object is a course grained solution. When the group
awakens every thread must do some work to find out if it is needed. Even if
each thread is running on a separate CPU it still requires operating system
CPU cycles to get the threads running and put the unnecessary threads back
into a blocking state.
Tymeac notifies each thread individually – only when it is needed. By
having a management structure for each Queue Thread, Tymeac knows the exact
status of each Queue Thread so there are no wasted cycles notifying
unnecessary threads.
Thread Pool
Tymeac's approach to the thread pool is to
have only the minimum number of threads running at any given time so that
Tymeac plays nice with other applications.
Tuning
Tymeac is tunable. Trying to manage traditional
pool threads is
like trying to herd cats.
Monitoring
Since Java threads execute at the application level there is no high level
manager to supervise the environment. Tymeac uses a
Monitor (daemon) at the application level that
periodically scans the environment looking for problems.
Exceptions
When thread exceptions occur, Tymeac doesn't just let the system print an ugly
message and kill the thread. Tymeac catches exceptions (including with an uncaught exception
handler), prints and logs meaningful messages with full documentation, and
notifies administrators of the problem.
Since most errors are with the user-written Classes (Developing Your Applications
discusses this in detail), Tymeac allows
dynamic repair and reload of those Classes with/without a
GUI and restarting of the disabled threads with/without a GUI.