The only time you must join a thread is when you care about the thread itself (not the thread
object). The only aspect of the thread that you have any kind of dependency on is the memory
used for the thread's stack. In POSIX and Win32 it is possible to "touch" the stack directly. This is
not possible in Java (a good thing), so the only possible interaction with the stack is the reuse issue.
If you start a new thread, will it have to allocate new memory or can it use the newly freed
memory from an exiting thread? Although it is possible to write a program where you can measure
this effect, it would be quite artificial.
POSIX and Win32 can return a status value and the same argument applies. It isn't the thread that
has status to return, it's the task that the thread was executing that has status, and that status may
be handled without calling join. In all honesty, there are plenty of programs that don't take our
advice and work just fine. You don't have to take our advice either, but you should consider it
before making your decision.
Exiting the Process
The semantics of exit() [in Java, System.exit()] are retained in MT programs in all the
libraries. When any thread in a process calls exit(), the process exits, returning its memory,
system resources, process structure, all LWPs, etc. In Java, if main() "falls off the bottom" of the
initial thread, the other threads will continue to run. [In the POSIX and Win32, the main thread
will make an implicit call to exit(), also killing the process. This is a requirement for them to
maintain compatibility with existing programs, not to mention the ANSI C spec.]
When any other thread in any of the libraries falls off the bottom of its initial function, it exits only
that one thread. [In POSIX and Win32, if the main thread calls the thread exit function directly,
that thread exits but does not call exit(), and the process continues.]
Finally, should all normal user threads exit (the library may create threads for its own use and they
will not be counted; see Daemon Threads), the thread library will detect this and call exit()
itself. This situation is not typical, however, as you will generally know when it's time to exit your
process. Instead of letting the threads die one by one, you should call System .exit() explicitly.
Suspending a Thread
Win32 and Java have a function to force a thread to suspend its execution for an arbitrary length
of time and a second function to cause the thread to resume [thread.suspend() and
thread.resume()]. These functions were included for the purpose of allowing such things as
garbage collectors and debuggers to gain full control of a process. As such, they are useful;
however, for almost any other purpose they are the wrong thing. Because a suspended thread may
hold locks that a controller thread needs, it is almost impossible to use suspension effectively. In
Java these methods have been deprecated in JDK 1.2. In POSIX and UNIX98, they don't exist at
They were to be included in UNIX98, and you may see reference to them, but they were dropped
out at the last minute.
It is possible for one thread to tell another thread to exit. This is known as cancellation in POSIX
and simply as killing a thread in Java and Win32 (Code Example 4-8). In theory it's quite simple.
T2 (Figure 4-3) tells T1 to exit, and it does. There is no relationship between the threads. Maybe
T2 created T1, maybe T3 created both of them, maybe something else.
Example 4-8 Cancellation in the Three Libraries
Search WWH :