Java 中的 JVM 关机钩10 Sept 2024 | 4 分钟阅读 开发人员可以使用一种称为关闭钩子的特定构造,在 JVM 关闭时插入一段代码来运行。当我们需要在 JVM 关闭时执行某些清理程序时,它很有用。 当虚拟机因用户外部原因(例如操作系统发出的终止请求)或由于资源问题(例如内存不足)而关闭时,使用常规构造(例如在应用程序退出前调用一个特殊过程(调用 System.exit(0)))将不起作用。关闭钩子允许我们提供一个任意代码块,该代码块将在 JVM 关闭时被调用,从而轻松解决此问题,正如我们稍后将看到的。 乍一看,使用关闭钩子似乎非常简单。要执行我们想要在虚拟机关闭时执行的逻辑,我们需要创建一个扩展 `java.lang.Thread` 类的类。 使用 Runtime.getRuntime() 方法使用 `Runtime.getRuntime()` 方法,可以在 Java 中创建关闭钩子。请观察以下程序。 文件名: ShutDownHook.java 输出 Application Terminating ... Shutdown Hook is running ! 通过扩展 Thread 类在这种情况下,我们必须将子线程添加到关闭钩子中。 文件名: ShutDownHook1.java 输出 3 X 1 = 3 3 X 2 = 6 3 X 3 = 9 3 X 4 = 12 3 X 5 = 15 3 X 6 = 18 3 X 7 = 21 3 X 8 = 24 3 X 9 = 27 3 X 10 = 30 In the clean up code In the shutdown hook 关于关闭钩子的要点在处理关闭钩子时,应牢记以下几点。 1. 在某些情况下,关闭钩子可能不会执行! 首先要记住的是,关闭钩子可能不总是执行。如果 JVM 由于内部故障而崩溃,它可能会在开始处理任何指令之前就发生。此外,如果操作系统发送 SIGKILL(在 Unix/Linux 中为 kill -9)或 TerminateProcess(Windows)信号,程序必须立即结束,甚至不需要等待任何清理程序。除了上述选项之外,还可以使用 `Runtime.halt()` 方法来终止 JVM,而无需启用关闭钩子。 当应用程序正常退出时(当所有线程都运行完毕或调用 `System.exit(0)` 时),会激活关闭钩子。此外,当 JVM 由于外部因素终止时,例如用户请求终止(Ctrl+C)、操作系统的 SIGTERM 信号(标准 kill 命令,不带 -9),或操作系统终止时。 2. 关闭钩子可以在开始后被强制终止,而无需完成。 实际上,这是前一种情况的一个特例。尽管钩子已经开始运行,但在操作系统关闭等情况下,它仍有可能过早结束。在这种情况下,在收到 SIGTERM 信号后,操作系统会等待一段时间以供进程结束。如果进程在此时间内未结束,操作系统将发出 SIGTERM(或 Windows 等效信号)以强制结束进程。因此,这可能会发生在关闭钩子执行过程中。因此,建议仔细构建关闭钩子,确保它们快速完成并且不会导致死锁等情况。此外,JavaDoc [1] 明确指出,不应该在关闭钩子中等待用户 I/O 操作或执行长时间计算。 3. 尽管许多关闭钩子的执行顺序无法保证。 您可以注册多个关闭钩子,正如您从 `addShutdownHook` 方法的名称(而不是 `setShutdownHook`)中可能已经正确推断出的那样。然而,JVM 不保证这些多个钩子将被执行的顺序。JVM 可能会以任何随机顺序执行关闭钩子。此外,JVM 可能会同时运行所有这些钩子。 4. 不允许在关闭钩子中注册或注销关闭钩子 一旦 JVM 开始关闭过程,就不可能添加新的关闭钩子或删除已有的关闭钩子。如果尝试这样做,JVM 将发出 `IllegalStateException`。 5. `Runtime.halt()` 是唯一可以在关闭序列开始后终止它的方法。 除了 SIGKILL 等外部影响外,一旦关闭序列开始执行,只有 `Runtime.halt()`(它会强制终止 JVM)才能中断其执行。因此,无法在关闭钩子中使用 `System.exit()`。实际上,如果您在关闭钩子中使用 `System.exit()`,VM 可能会卡住,在这种情况下,我们可能需要强制终止进程。 6. 使用关闭钩子需要安全权限。 如果正在使用 Java 安全管理器,则添加或删除关闭钩子的代码必须具有运行时访问关闭钩子权限的权限。如果在安全环境中未经授权调用此方法,将抛出 `SecurityException`。 下一主题Java中的半素数 |
Java Collections 框架中的 `checkedQueue()` 方法可用于在运行时使队列类型安全,因此它是一个非常有效且重要的实用程序,正因如此,`checkedQueue()` 方法位于 `Collections` 类中,并且可以...
14 分钟阅读
Go 和 Java 都是被全球大量开发人员使用的语言。由于这两种语言都提供服务器端编程的功能,因此选择其中一种可能是一项艰巨的任务。在本节中,我们讨论了它们之间的主要区别...
阅读 3 分钟
数字图像分析和计算机视觉都严重依赖于图像处理。为了获得预期的结果,这需要图像的修改。Java 有许多功能强大且特性丰富的库。使用它们,我们可以操纵图像。图像方向的操纵...
阅读 6 分钟
旋转位问题涉及将整数的位向左或向右移动,将溢出的位包装到另一端。此操作在低级编程、加密和数据操作任务中至关重要。Java 提供了按位运算符来高效地为两者实现此功能...
7 分钟阅读
Java 8 引入了对 Stream API 的重大增强,这彻底改变了我们处理数据集合的方式。Stream 提供了一种流畅高效的数据操作方法,为数据操作提供了函数式编程方法。在本节中,我们将探讨...
阅读 4 分钟
给我们一个整数计数,与一个由小写英文字母组成的字符串 'str' 相关联。此特定问题的目标是查找“相等计数子串”。当子串中的每个不同字母都出现恰好 count 次时,该子串称为...
阅读 6 分钟
在 Java 中,Variant 是一个类,它定义在两个不同的包中。javax.ws.rs.core.Variant org.eclipse.swt.ole.win32.Variant javax.ws.rs.core.Variant 它内置于 JDK 中。该类属于 javax.ws.rs.core.Variant。它扩展了 Object 类。该类用于表示资源表示的变体,其中包含有关媒体类型、语言...的信息。
阅读 3 分钟
ZIP 是一种常见的文件格式,可将一个或多个文件压缩到一个位置。它减小了文件大小,并使其更易于传输或存储。接收者可以在传输后解压缩(或提取)ZIP 文件并使用文件...
阅读 8 分钟
已检查异常是在编译时检查的异常。它也称为编译时异常。Java 编译器强制开发人员处理它。如果可能抛出已检查异常的任何方法没有使用 try-catch 块处理它或使用...声明它。
7 分钟阅读
在 Java 中,先决条件是指在任何特定方法或操作可以开始执行之前必须达到的状态或条件。它有助于检查所有方法的参数是否正确,以及对象或系统的状态是否适合……
5 分钟阅读
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India