THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

In rare circumstances, the virtual machine will abort rather than perform an orderly shutdown. This can
happen, for example, if an internal error is detected in the virtual machine that prevents an orderly
shutdownsuch as errant native code overwriting system data structures. However, the environment hosting the
virtual machine can also force the virtual machine to abortfor example, under UNIX systems a SIGKILL
signal will force the virtual machine to abort. When the virtual machine is forced to terminate in this way, no
guarantees can be made about whether or not shutdown hooks will run.


23.3.3. Shutdown Strategies


Generally, you should let a program finish normally rather than forcibly shut it down with exit. This is
particularly so with multithreaded programs, where the thread that decides it is time for the program to exit
may have no idea what the other threads are doing.


Designing a multithreaded application in a way that makes it safe to exit at arbitrary points in the program is
either trivial or extremely complex. It is trivial when none of the threads are performing actions that must be
completedfor example, having a thousand threads all trying to solve a numerical problem. It is complex
whenever any of the threads perform actions that must be completed.


You can communicate the fact that shutdown is required by writing your threads to respond to the
interrupt methodas you learned on page 365. You can broadcast the shutdown request to all your threads
by invoking the interrupt method of the parent ThreadGroup of your application. This is no guarantee
that a program will terminate, however, because libraries that you have used may have created user threads
that do not respond to interrupt requeststhe AWT graphics library is one well-known example.


There are two circumstances when you must invoke exit: when it is the only way to terminate some of the
threads and hence your application, and when your application must return a status code. In both cases you
need to delay the call to exit until all your application threads have had a chance to terminate cleanly. One
way is for the thread initiating the termination to join the other threads and so know when those threads
have terminated. However, an application may have to maintain its own list of the threads it creates because
simply inspecting the ThreadGroup may return library threads that do not terminate and for which join
will not return.


The decision to shutdown a program should be made at a high-level within the applicationoften within main
or the run method of a thread in the top-level application ThreadGroup or in the code that responds to
events in a graphical user interface. Methods that encounter errors should simply report those errors via
exceptions that allow the high-level code to take appropriate action. Utility code should never terminate an
application because it encounters an errorthis code lacks knowledge of the application that allows an informed
decision to be made; hence, exceptions are used to communicate with higher-level code.


23.4. The Rest of Runtime


The Runtime class provides functionality in six different areas:



  • Interacting with the garbage collector and querying memory usage

  • Asking for the number of processors available

  • Executing external programs

  • Terminating the current Runtime

  • Loading native code libraries

  • Debugging

Free download pdf