首页 > 解决方案 > 当关闭挂钩或终结器未完成时会发生什么?

问题描述

实践中的 Java 并发说:

在有序关闭中,JVM 首先启动所有已注册的关闭挂钩。关闭挂钩是使用 Runtime.addShutdownHook 注册的未启动线程。JVM 不保证关闭挂钩的启动顺序。如果任何应用程序线程(守护程序或非守护程序)在关闭时仍在运行,它们将继续与关闭进程同时运行。当所有关闭挂钩都完成后,如果 runFinalizersOnExit 为真,JVM 可能会选择运行终结器,然后停止。JVM 不会尝试停止或中断任何在关闭时仍在运行的应用程序线程;当 JVM 最终停止时,它们会突然终止。如果关闭钩子或终结器未完成,则有序关闭过程“挂起”,JVM 必须突然关闭。在突然关闭时,除了停止 JVM 之外,不需要 JVM 做任何事情;关闭挂钩将不会运行。

我理解除了“如果关闭挂钩或终结器没有完成,那么有序关闭过程“挂起”并且必须突然关闭 JVM。” .

“有序关机进程“挂起”是什么意思?如果关闭钩子或终结器没有完成,它会阻止 JVM 被关闭,为什么它说“JVM 必须突然关闭”?

// shutdown hook prevent JVM from being shut down

package com.example.schedulerdemo;

import java.util.concurrent.TimeUnit;

public class EndlessShutdownHook {

    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("shutdown hook started");
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(15);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("loop");
            }
        }));

        // this thread will still run after I shutdown the application because of the endless shutdown hook
        new Thread(() -> {
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("fixed Rate Task");
            }
        }).start();
    }
}

标签: javamultithreadingshutdown-hook

解决方案


推荐阅读