To shut down an application, all application created non-daemon threads must exit to trigger the JVM shutdown sequence. The following approaches can be used to manage non-daemon application threads:
Do not return from main
until all non-daemon
application threads exit.
Signal and wait, in an application specific manner, for all non-daemon threads to exit, from a shutdown hook
Signal and wait, in an application specific manner, for all non-daemon threads to exit, from a component notifier
Example 3.2, “Managing Threads with Join” shows the use of
Thread.join()
to block in main
until
all non-daemon application threads exit.
Example 3.2. Managing Threads with Join
// $Revision: 1.1.2.1 $ package com.kabira.snippets.vmlifecycle; /** * Using join to coordinate thread termination * <p> * <h2> Target Nodes</h2> * <ul> * <li> <b>domainnode</b> = A * </ul> */ public class Join { /** * Application thread */ static public class MyThread extends Thread { @Override public void run() { System.out.println("hello from the thread"); } } /** * Main entry point * @param args Not used */ public static void main(String[] args) { // // Create and start a new thread // MyThread t = new MyThread(); t.run(); // // Wait for the thread to return before exiting main // try { t.join(); } catch (InterruptedException ex) { // handle interrupted exception } // // Returning from main - causes the JVM to exit // System.out.println("returning from main"); } }
Example 3.3, “Daemon Threads” shows how a thread can be marked as a daemon thread. Daemon threads can be used by an application if the thread termination does not need to be coordinated with the JVM being shut down.
Example 3.3. Daemon Threads
// $Revision: 1.1.2.1 $ package com.kabira.snippets.vmlifecycle; /** * Using daemon threads * <p> * <h2> Target Nodes</h2> * <ul> * <li> <b>domainnode</b> = A * </ul> */ public class Daemon { /** * Application thread */ public static class MyThread extends Thread { @Override public void run() { try { System.out.println("thread sleeping..."); Thread.sleep(5000); } catch (InterruptedException ex) { // Handle exception } } } /** * Main entry point * @param args Not used */ public static void main(String[] args) { // // Create a new thread // MyThread t = new MyThread(); // // Mark the thread as a daemon thread // t.setDaemon(true); // // Start the thread // t.run(); // // Returning from main - causes the JVM to exit // System.out.println("returning from main"); } }