Shutdown Hook 是已初始化但未啟動的執行緒,註冊至 Runtime.getRuntime()。當 JVM 正常關閉時,這些 Hook 會並發啟動並執行清理邏輯。
Runtime.getRuntime().addShutdownHook(Thread hook);
Thread 實例(通常實作 Runnable)。package john2;
public class ShutdownHookDemo implements Runnable {
public ShutdownHookDemo() {
// 註冊 hook
Runtime.getRuntime().addShutdownHook(new Thread(this));
System.out.println(">>> Shutdown hook registered");
}
@Override
public void run() {
System.out.println("\n>>> Executing cleanup before JVM exit...");
cleanUp();
System.out.println(">>> Cleanup finished.");
}
private void cleanUp() {
// 模擬釋放資源:關閉連線池、刷新日誌、保存狀態等
for (int i = 0; i < 5; i++) {
System.out.println("Cleanup step " + (i+1));
try { Thread.sleep(200); } catch (InterruptedException ignored) {}
}
}
public static void main(String[] args) throws InterruptedException {
new ShutdownHookDemo();
System.out.println(">>> Sleeping 5s, try Ctrl+C to trigger hook...");
Thread.sleep(5000);
System.out.println(">>> Main thread exiting, JVM will shutdown.");
}
}
System.exit(int) 被呼叫Runtime.halt() 強制終止kill -9 (SIGKILL) 強制殺死進程Hook 執行緒在註冊時未啟動,不佔用 CPU/記憶體資源(除 Thread 物件本身)。僅在關閉時啟動,對運行期零影響。
System.exit() 前手動協調。ConfigurableApplicationContext.registerShutdownHook() 內部即使用此機制關閉容器。// 錯誤:在 Hook 中啟動新執行緒做耗時任務
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
new Thread(() -> heavyCleanup()).start(); // 主 Hook 結束,JVM 可能直接退出,子執行緒被殺
}));
// 正確:在 Hook 內同步完成,或使用 CountDownLatch 等待關鍵非守護執行緒