【Java基础】JVM关闭回调函数(ShutdownHook)的应用场景

文章目录

    • 一.ShutdownHook介绍
    • 二.ShutdownHook被调用场景
    • 三.ShutdownHook如何使用
    • 四.ShutdownHook实践

一.ShutdownHook介绍

  • ShutdownHook就是一个简单的 已初始化 但是 未启动 的 线程 。当虚拟机开始关闭时,它将会调用所有已注册ShutdownHook的回调函数,这些回调函数执行是并发的,执行顺序是不确定的

    • 作用:JVM退出时执行的业务逻辑( 注意:ShutdownHook方法参数必须是Thread的子类,由此得知,ShutdownHook是异步执行的。
      • 添加:Runtime.getRuntime(). addShutdownHook(Thread var1)
      • 移除:Runtime.getRuntime().removeShutdownHook(this.shutdownHookThread)
  • 需要注意的是,在ShutdownHook里执行的操作应当是不太耗时的。因为在用户注销或者操作系统关机导致的JVM shutdown的例子中,系统只会预留有限的时间给未完成的工作,超时之后还是会强制关闭。

二.ShutdownHook被调用场景

  • 程序正常退出
  • 程序调用 System.exit() 退出
  • 终端使用 Ctrl+C 中断程序
  • 程序抛出异常导致程序退出,例如 OOM,数组越界等异常
  • 系统事件,例如用户注销或关闭系统
  • 使用 Kill pid 命令杀掉进程,注意使用 kill -9 pid 强制杀掉不会触发执行钩子

三.ShutdownHook如何使用

调用java.lang.Runtime这个类的addShutdownHook(Thread hook)方法即可注册一个ShutdownHook,然后在Thread中定义需要在system exit时进行的操作。如下:

Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Do something in ShutdownHook")
));

测试例子

  • 首先,注册了一个ShutdownHook。
    • 然后,系统Sleep 3秒,模拟进行某些操作。
      • 然后,调用一个空的List,抛出异常,准备结束程序。
        • 在程序将要结束的时候,执行ShutdownHook中的内容。
public static void main(String[] args)
{// register ShutdownHookRuntime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Do something in ShutdownHook")));// sleep for some timetry {for (int i=0; i<3; i++) {System.out.println("Count: " + i + "...");TimeUnit.MILLISECONDS.sleep(1000);}List nullList = new ArrayList<>();System.out.println("Trying to print null list's first element: " + nullList.get(0).toString());} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Ready to exit.");System.exit(0);
}

结果如下:

Count: 0...
Count: 1...
Count: 2...
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0at java.util.ArrayList.rangeCheck(ArrayList.java:653)at java.util.ArrayList.get(ArrayList.java:429)at HookTest.main(HookTest.java:18)
Do something in ShutdownHookProcess finished with exit code 1

需要注意的点

  • 当System.exit之后,当ShutdownHook开始执行时,其他的线程还是会继续执行
  • 应当保证ShutdownHook的线程安全。
    • 在使用多个ShutdownHook时一定要特别小心,保证其调用的服务不会被其他Hook影响。否则会出现当前Hook所依赖的服务被另外一个Hook终止了的情况。

四.ShutdownHook实践

例如,我们程序自定义了一个线程池,用来接收和处理任务。如果程序突然崩溃异常退出,这时线程池的所有任务有可能还未处理完成,如果不处理完程序就直接退出,可能会导致数据丢失,业务异常等重要问题。这时钩子就派上用场了。

 import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;public class ShutdownHookDemo {// 线程池private static ExecutorService executorService = Executors.newFixedThreadPool();static {Runtime.getRuntime().addShutdownHook(new Thread(() -> {System.out.println("开始执行钩子方法...");// 关闭线程池executorService.shutdown();try {// 等待秒System.out.println(executorService.awaitTermination(, TimeUnit.SECONDS));} catch (InterruptedException e) {e.printStackTrace();}System.out.println("结束执行钩子方法...");}));}public static void main(String[] args) throws InterruptedException {System.out.println("程序开始启动...");// 向线程池添加个任务for (int i =; i < 10; i++) {Thread.sleep();final int finalI = i;executorService.execute(() -> {try {Thread.sleep();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Task " + finalI + " execute...");});System.out.println("Task " + finalI + " is in thread pool...");}}
} 

在命令行窗口中运行程序,在10个任务都提交到线程池之后,任务都还未处理完成之前,使用Ctrl+C中断程序,最终在虚拟机关闭之前,调用了关闭回调函数,关闭线程池,并且等待60秒让所有任务执行完成。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/647495.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt 基于海康相机 的视频标绘

需求&#xff1a; 基于 视频 进行 标注&#xff0c;从而进行测量。 曾经搞在线教育时&#xff0c;尝试在视频上进行文字或者图形的绘制&#xff0c;但是发现利用Qt widget 传sdk 句柄的方式&#xff0c;只能使用窗口叠加的方式&#xff08;Qt 基于海康相机的视频绘图_海康相…

专业144总分410+华南理工大学811信号与系统考研经验华工电子信息与通信

今年专业811信号与系统144&#xff08;二战&#xff0c;感谢信息通信Jenny老师专业课对我的巨大提高&#xff0c;第一年自己复习只考了90&#xff0c;主要栽专业课和数学&#xff09;总分410含泪&#xff08;二战的同学都知道苦&#xff0c;成功来之不易&#xff09;考上华南理…

java servlet 高校田径运动会管理系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 jsp高校田径运动会管理系统是一套完善的java web信息管理系统 采用mvc模式 servletdaobean 模式开发&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myecl…

Kafka-消费者-KafkaConsumer分析总结

KafkaConsumer依赖SubscriptionState管理订阅的Topic集合和Partition的消费状态&#xff0c;通过ConsumerCoordinator与服务端的GroupCoordinator交互&#xff0c;完成Rebalance操作并请求最近提交的offset。 Fetcher负责从Kafka中拉取消息并进行解析&#xff0c;同时参与posi…

[git] windows系统安装git教程和配置

一、何为Git Git(读音为/gɪt/)是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。 二、git安装包 有2种版本&#xff0c;Git for Windows Setup和Git for Windows Portable(便携版)两个版本都可以。 三、Git for Windows Por…

手动搭建koa+ts项目框架(apidoc文档篇)

文章目录 一、安装apidoc工具二、使用1、项目根目录新建apidoc.json2、定义接口路由上方注解对应信息3、配置静态文件访问目录4、生成api文档如有启发&#xff0c;可点赞收藏哟~ 一、安装apidoc工具 全局安装 npm i apidoc -g查看是否安装成功 apidoc -v二、使用 1、项目根…

1. MySQL 数据库

本章内容 关系型数据库基础 安装 MySQL 管理数据库和表 用户和权限管理 函数&#xff0c;存储过程&#xff0c;触发器和事件 MySQL 架构 存储引擎 服务器选项&#xff0c;系统和状态变量 优化查询和索引管理 锁和事务管理 日志管理 备份还原 MySQL 集群 压力测试…

linux-centos服务器离线安装yapi(包含nodejs、mongodb、yapi、pm2离线安装)

yapi是使用vue框架开发的,借助nodejs 前端直接访问的mongodb数据库,离线安装yapi步骤如下 下载离线安装包 下载地址 https://download.csdn.net/download/qq445829096/88778418 离线安装包先复制到 dev/yapi目录(根据自己习惯自定义目录) node-v12.13.0-linux-x64.tar.xz …

群辉NAS的远程访问

群辉NAS是私有云存储&#xff0c;局域网访问很容易【详见&#xff1a;网上邻居访问设置、其它设备的访问设置】&#xff0c;远程访问相对复杂&#xff0c;涉及很多关键因素&#xff0c;现将过程记录如下&#xff1a; 目录 1、互联网接入 2、绑定MAC与IP地址 3、路由器开启5…

SpringMVC-HttpMessageConverter 报文信息转化器

文章目录 HttpMessageConverter一、概念二、RequestBody三、RequestEntity四、 ResponseBody1.返回JSON格式的字符串 五、RestController六、ResponseEntity HttpMessageConverter 一、概念 报文信息转化器&#xff0c;将请求报文转化为Java对象&#xff0c;或将Java对象转化…

Java笔记(死锁、线程通信、单例模式)

一、死锁 1.概述 死锁 : 死锁是指两个或两个以上的进程在执行过程中&#xff0c;由于竞争资源或者由于彼此通信而造成的一种阻塞的现象&#xff0c;若无外力作用&#xff0c;它们都将无法往下执行。此时称系统处于死锁状态或系统产生了死锁&#xff0c;这些永远在互相等待的进…

Leetcode 俩数之和(哈希)

一、题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以…

【LMDeploy 大模型量化部署实践】学习笔记

参考学习教程【LMDeploy 的量化和部署】 理论 作业 使用 LMDeploy 以本地对话、网页Gradio、API服务中的一种方式部署 InternLM-Chat-7B 模型&#xff0c;生成 300 字的小故事 本地对话 API服务 Client 命令 端口转发 网页Gradio

一文学习Thrift RPC

Thrift RPC引言 Thrift RPC的特点 Thrift 是一个RPC的框架&#xff0c;和Hessian RPC有什么区别&#xff0c;最重要的区别是Thrift可以做异构系统开发。 什么是异构系统&#xff0c;服务的提供者和服务的调用者是用不同语言开发的。 为什么会当前系统会有异构系统的调用&…

【WPF.NET开发】WPF 中的 Layout

本文内容 元素边界框布局系统测量和排列子元素面板元素和自定义布局行为布局性能注意事项子像素渲染和布局舍入 本主题介绍 Windows Presentation Foundation (WPF) 布局系统。 了解布局计算发生的方式和时间对于在 WPF 中创建用户界面非常重要。 1、元素边界框 在 WPF 中构…

Apollo Cyber RT:引领实时操作系统在自动驾驶领域的创新

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下…

深入理解旅游网站开发:Java+SpringBoot+Vue+MySQL的实战经验

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

ChatGPT 全域调教高手:成为人工智能交流专家

随着人工智能的快速发展&#xff0c;ChatGPT作为一种强大的文本生成模型&#xff0c;在各行各业中越来越受到重视和应用。想要利用ChatGPT实现更加智能、自然的交流&#xff0c;成为 ChatGPT 全域调教高手吗&#xff1f;本文将为您介绍如何通过优化ChatGPT的训练方法&#xff0…

jquery多选框

使用hbuilder <!DOCTYPE html> <html><head><meta charset"GBK"><title></title></head><body><table id"myTable"> <tr> <td>黄1</td> </tr> <tr> <td>…

JAVA泛型、泛型通配符、综合练习

作用&#xff1a; 是 jdk5 中引入的特性&#xff0c;可以在编译阶段 约束 操作的数据类型&#xff0c;并进行检查。 格式&#xff1a; <数据类型> 注意泛型只能支持引用数据类型&#xff0c;基本数据类型可转成对应的包装类。 问题&#xff1a; 在没有泛型的时候&…