Java Reference
In-Depth Information
Somewhat confusingly, exceptions thrown from tasks make it to the uncaught exception
handler only for tasks submitted with
execute
; for tasks submitted with
submit
,
any
thrown exception, checked or not, is considered to be part of the task's return status. If a
task submitted with
submit
terminates with an exception, it is rethrown by
Future.get
,
wrapped in an
ExecutionException
.
7.4. JVM Shutdown
The JVM can shut down in either an
orderly
or
abrupt
manner. An orderly shutdown is initi-
ated when the last “normal” (nondaemon) thread terminates, someone calls
System.exit
,
or by other platform-specific means (such as sending a
SIGINT
or hitting
Ctrl-C
). While
this is the standard and preferred way for the JVM to shut down, it can also be shut down
abruptly by calling
Runtime.halt
or by killing the JVM process through the operating
system (such as sending a
SIGKILL
).
7.4.1. Shutdown Hooks
In an orderly shutdown, the JVM first starts all registered
shutdown hooks
. Shutdown hooks
are unstarted threads that are registered with
Runtime.addShutdownHook
. The JVM
makes no guarantees on the order in which shutdown hooks are started. If any application
threads (daemon or nondaemon) are still running at shutdown time, they continue to run con-
currently with the shutdown process. When all shutdown hooks have completed, the JVM
may choose to run finalizers if
runFinalizersOnExit
is
true
, and then halts. The
JVM makes no attempt to stop or interrupt any application threads that are still running at
shutdown time; they are abruptly terminated when the JVM eventually halts. If the shutdown
hooks or finalizers don't complete, then the orderly shutdown process “hangs” and the JVM
must be shut down abruptly. In an abrupt shutdown, the JVM is not required to do anything
other than halt the JVM; shutdown hooks will not run.
Shutdown hooks should be thread-safe: they must use synchronization when accessing shared
data and should be careful to avoid deadlock, just like any other concurrent code. Further,
they should not make assumptions about the state of the application (such as whether other
services have shut down already or all normal threads have completed) or about why the JVM
is shutting down, and must therefore be coded extremely defensively. Finally, they should
exit as quickly as possible, since their existence delays JVM termination at a time when the
user may be expecting the JVM to terminate quickly.