public class TestApplication { public static void main(String[] args) { Thread logbackShutdownHook = new Thread(new LogbackShutdownHook()); Runtime.getRuntime().addShutdownHook(logbackShutdownHook); Thread appShutdownHook = new Thread(new AppShutdownHook()); Runtime.getRuntime().addShutdownHook(appShutdownHook); try { Thread.sleep(30000); } catch (InterruptedException ignored) { } System.err.println("TestApplication exited normally"); } private static class LogbackShutdownHook implements Runnable { @Override public void run() { System.err.println("LogbackShutdownHook started"); try { Thread.sleep(2000); } catch (InterruptedException ignored) { } System.err.println("LogbackShutdownHook finished"); } } private static class AppShutdownHook implements Runnable { @Override public void run() { System.err.println("AppShutdownHook started"); try { Thread.sleep(10000); } catch (InterruptedException ignored) { } System.err.println("AppShutdownHook finished"); } } }