Java虚拟机关闭钩子(Shutdown hook)

简介: Shutdown hook是Jvm关闭的钩子,是通过Runtime#addShutdownHook(Thread hook)方法来实现的,根据api是注解可知它就是一系例的已初始化但尚未执行的线程对象。我们可以通过向Jvm注册一个钩子,实现在程序退出时关闭资源、平滑退出的功能。所谓的优雅停机也可以这么搞。

Shutdown hook是什么

Shutdown hook是Jvm关闭的钩子,是通过Runtime#addShutdownHook(Thread hook)方法来实现的,根据api是注解可知它就是一系例的已初始化但尚未执行的线程对象。我们可以通过向Jvm注册一个钩子,实现在程序退出时关闭资源、平滑退出的功能。所谓的优雅停机也可以这么搞。

Jvm关闭的方式

img

程序只有在正常关闭和异常关闭的情况下才会调用钩子函数坐一些扫尾的工作,如果是强制关闭的则不会调用,强制关闭直接无商量终止jvm进程,不给jvm喘息的机会。

使用关闭钩子的注意事项

  • 关闭钩子本质上是一个线程(也称为Hook线程),对于一个JVM中注册的多个关闭钩子它们将会并发执行,所以JVM并不保证它们的执行顺序;由于是并发执行的,那么很可能因为代码不当导致出现竞态条件或死锁等问题,为了避免该问题,强烈建议在一个钩子中执行一系列操作。
  • Hook线程会延迟JVM的关闭时间,这就要求在编写钩子过程中必须要尽可能的减少Hook线程的执行时间,避免hook线程中出现耗时的计算、等待用户I/O等等操作。
  • 关闭钩子执行过程中可能被强制打断,比如在操作系统关机时,操作系统会等待进程停止,等待超时,进程仍未停止,操作系统会强制的杀死该进程,在这类情况下,关闭钩子在执行过程中被强制中止。
  • 在关闭钩子中,不能执行注册、移除钩子的操作,JVM将关闭钩子序列初始化完毕后,不允许再次添加或者移除已经存在的钩子,否则JVM抛出 IllegalStateException。
  • 不能在钩子调用System.exit(),否则卡住JVM的关闭过程,但是可以调用Runtime.halt()。
  • Hook线程中同样会抛出异常,对于未捕捉的异常,线程的默认异常处理器处理该异常,不会影响其他hook线程以及JVM正常退出

简单例子(具体可看源码)

1.业务要关闭的资源

public class StudyResource implements AutoCloseable {

    @Override
    public void close() throws Exception {
        System.out.println("执行项目资源关闭操作");
    }
}

2.自定义钩子

/**
 * @author: lixiaoshuang
 * @create: 2020-11-25 20:48
 **/
public class StudyShtudownHook extends Thread {

    private static final StudyShtudownHook INSTANCE = new StudyShtudownHook();
    /**
     * 需要关闭的钩子集合,可以将项目中的资源关闭操作都放在这里
     */
    private final Set<AutoCloseable> autoCloseableHashSet = new HashSet<>();


    private StudyShtudownHook() {

    }

    public static StudyShtudownHook getInstance() {
        return INSTANCE;
    }


    public void registerAutoCloseable(final AutoCloseable autoCloseable) {
        autoCloseableHashSet.add(autoCloseable);
    }

    @Override
    public void run() {
        this.closeAll();
    }

    @SneakyThrows
    private void closeAll() {
        for (AutoCloseable autoCloseable : autoCloseableHashSet) {
            autoCloseable.close();
        }
    }
}
  1. 向jvm注册钩子
public class JvmHookDemo {

    public static void main(String[] args) throws InterruptedException {
        
        //自己实现的钩子
        StudyShtudownHook instance = StudyShtudownHook.getInstance();
        //将需要关闭的资源放到钩子里
        StudyResource studyResource = new StudyResource();
        instance.registerAutoCloseable(studyResource);

        //向jvm注册钩子
        Runtime.getRuntime().addShutdownHook(instance);

        System.out.println("执行业务逻辑。。。。");
        Thread.sleep(5000);
        System.out.println("业务逻辑处理完毕。。。。");
    }
}

执行这段代码后输出:

执行业务逻辑。。。。

业务逻辑处理完毕。。。。

执行项目资源关闭操作

目录
相关文章
|
6天前
|
Java 数据库连接 开发者
Java的Shutdown Hook机制:优雅地关闭应用程序
Java的Shutdown Hook机制:优雅地关闭应用程序
22 1
|
6天前
|
存储 Java 数据安全/隐私保护
【JVM】Java虚拟机栈(Java Virtual Machine Stacks)
【JVM】Java虚拟机栈(Java Virtual Machine Stacks)
39 0
|
6天前
|
监控 Oracle Java
《深入浅出Java虚拟机 — JVM原理与实战》带你攻克技术盲区,探索各大JVM虚拟机特色 —— JVM故障排除指南(先导篇)
《深入浅出Java虚拟机 — JVM原理与实战》带你攻克技术盲区,探索各大JVM虚拟机特色 —— JVM故障排除指南(先导篇)
45 0
|
6天前
|
存储 Java
深入理解Java虚拟机:JVM内存模型
【4月更文挑战第30天】本文将详细解析Java虚拟机(JVM)的内存模型,包括堆、栈、方法区等部分,并探讨它们在Java程序运行过程中的作用。通过对JVM内存模型的深入理解,可以帮助我们更好地编写高效的Java代码,避免内存溢出等问题。
|
6天前
|
缓存 算法 安全
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(二)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
23 0
|
6天前
|
缓存 Java C#
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(一)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
92 0
|
1天前
|
算法 Java 编译器
从Java字节码到JIT编译器,深入理解Java虚拟机
Java虚拟机(JVM)是Java程序运行的关键。想深入理解Java虚拟机,我们需要了解Java字节码、类加载机制、垃圾回收算法、JIT编译器等方面的知识。本文将介绍这些关键知识点,并通过示例代码加深理解。
|
6天前
|
Linux Windows
FinalShell连接Linux虚拟机报错java.net.ConnectException: Connection timed out: connect(亲测有效)
FinalShell连接Linux虚拟机报错java.net.ConnectException: Connection timed out: connect(亲测有效)
231 0
|
6天前
|
存储 Java 开发者
深入理解Java虚拟机(JVM)内存管理
【2月更文挑战第11天】 在本篇文章中,我们将深入探讨Java虚拟机(JVM)的内存管理机制,一项对于优化Java应用性能至关重要的技术领域。不同于常规的技术文章摘要,我们不仅概述了JVM内存管理的基本概念,还将引导读者通过实际案例理解其在现实世界应用中的重要性。从堆(Heap)和栈(Stack)的区别开始,到垃圾收集(Garbage Collection)机制的工作原理,本文旨在为Java开发者提供一个清晰、系统的JVM内存管理知识框架,帮助他们在开发过程中做出更加明智的决策。
|
6天前
|
存储 算法 Java
Java虚拟机内存管理机制
【2月更文挑战第7天】本文主要介绍了Java虚拟机内存管理机制的基本原理和实现方式。Java虚拟机的内存管理机制是Java程序运行的重要组成部分,对程序性能和稳定性有着直接的影响。文章首先从Java虚拟机内存模型入手,介绍了Java虚拟机中堆内存、方法区、栈、PC寄存器等内存区域的功能特点和使用方式;然后详细阐述了Java虚拟机内存管理机制的垃圾回收算法和回收器的分类、优化和实现过程;最后介绍了一些常见的内存问题和优化技巧,以及如何通过代码调优和合理使用内存配置参数来提高程序的性能和稳定性。

热门文章

最新文章