14.12.1. Don't stop
We mentioned in Chapter 12 that two forms of asynchronous exceptions are definedinternal errors in the Java
virtual machine, and exceptions caused by the invocation of the deprecated Thread.stop method.
As a general rule we don't discuss deprecated methods in this book, but stop is specialpartly because of what
it does, but mostly because it is, as they say, "out there" and you may well come across code that uses it (or
tries to).
The stop method causes an asynchronous ThreadDeath exception to be thrown in the thread on which it
is invoked. There is nothing special about this exceptionjust like any other exception it can be caught, and if it
is not caught it will propagate until eventually the thread terminates. The exception can occur at almost any
point during the execution of a thread, but not while trying to acquire a lock.
The intent of stop was to force a thread to terminate in a controlled manner. By throwing an exception that
was unlikely to be caught, it allowed the normal cleanup procedure of using finally clauses to tidy up as
the thread's call stack unwound. But stop failed to achieve this in two ways. First, it couldn't force any
thread to terminate because a thread could catch the exception that was thrown and ignore ithence it was
ineffective against malicious code. Second, rather than allowing a controlled cleanup, it actually allowed the
corruption of objects. If stop was invoked while a thread was in a critical section, the synchronization lock
would be released as the exception propagated, but the object could have been left in a corrupt state due to the
partial completion of the critical section. Because of these serious flaws stop was deprecated. Instead,
interrupt should be used for cooperative cancellation of a thread's actions.
A second form of stop took any THRowable object as an argument and caused that to be the exception
thrown in the target threadthis is even more insidious because it allows "impossible" checked exceptions to be
thrown from code that doesn't declare them.
14.12.2. Stack Traces
Any thread that is alive, can be queried for its current execution stack trace. The getStackTrace method
returns an array of StackTraceElement objectsas described in "Stack Traces" on page 294where the
zeroth element represents the currently executing method of the thread. If the thread is not alive then a
zero-length array is returned.
You can access the stack traces of all threads in the system using the static THRead class method
getAllStackTraces, which returns a map from each thread to its corresponding
StackTraceElement array.
Stack trace information is generally used for debugging and monitoring purposesfor example, if your
application "hangs," a monitoring thread might display all the stack traces, showing you what each thread is
doing. Of course, if your application hangs because of an error in your code, any such monitoring thread may
itself not get a chance to execute. The virtual machine is not required to produce non-zero-length stack traces
for any given thread, and it is also allowed to omit some methods from the stack trace information.
14.13. THReadLocal Variables
The THReadLocal class allows you to have a single logical variable that has independent values in each
separate thread. Each THReadLocal object has a set method that lets you set the value of the variable in
the current thread, and a get method that returns the value for the current thread. It is as if you had defined a
new field in each thread class, but without the need to actually change any thread class. This is a feature you