Startup, shutdown and exit codes
main() returning is not the end. The JVM runs until the last non-daemon thread stops.
Open this lesson in the learning hubKey points
- The JVM exits when the last non-daemon thread finishes, not when
mainreturns. One forgotten thread keeps it alive. - A daemon thread never holds the JVM open. It is killed wherever it happens to be, so never put work that must finish on one.
Runtime.addShutdownHookregisters a thread to run on exit. Hooks run in parallel, in no order, and usually get only seconds.System.exit(n)runs the hooks and leaves with status n.Runtime.halt(n)skips them completely.- No hook runs on
SIGKILLor a kernel OOM-kill, so never make correctness depend on one. Flush as you go instead.
Example
public class Main {
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread(() ->
System.out.println("3. shutdown hook: flush logs, close the pool, then exit 0")));
Thread poller = new Thread(() -> {
while (true) {
try { Thread.sleep(20); } catch (InterruptedException e) { return; }
}
}, "poller");
poller.setDaemon(true); // a daemon never holds the JVM open
poller.start();
Thread worker = new Thread(() -> {
try { Thread.sleep(300); } catch (InterruptedException e) { return; }
System.out.println("2. worker finished - that was the last non-daemon thread");
}, "worker");
worker.start(); // not a daemon, so the JVM must wait for it
System.out.println("1. main() is returning now, and the process is still alive");
System.out.println(" poller (daemon) alive = " + poller.isAlive() + ", counts towards exit = no");
System.out.println(" worker (normal) alive = " + worker.isAlive() + ", counts towards exit = yes");
System.out.println();
System.out.println("Nothing below this line runs on the main thread.");
}
}
The process ends with the last non-daemon thread, not with main().
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the JVM course, and every lesson in it is listed on the JVM contents page.