JAVA Runtime.addShutdownHook()方法{拿到线程句柄,在程序关闭之前调用释放资源}
Runtime#addShutDownHook方法是给虚拟机增加一个虚拟机关闭时的调用钩子,在虚拟机关闭的时候调用这些钩子线程。还是非常有用的一个方法,最直接的用法就是监控了,因为其是在虚拟机临关闭时被调用,所以天生可以记录虚拟机关闭这件事情,及其相关的信息;再就是清理资源什么的,也可以做一个钩子线程,这样就不用再应用中为这些清理资源的操作找合适的位置了;
下面先翻译一下这个方法的Java doc,在网上找到几篇翻译,都出自一个版本,错误挺多的,这里重新翻译一下:
doc的第一句话是Registers a new virtual-machine shutdown hook.网上的翻译的版本将其翻译成了注册一个新的虚拟机来关闭钩子,这样翻译从语法的角度来讲就是不对的嘛,一句话里Register和Shutdown都成了动词。很简单的一句话,就是注册一个新的虚拟机关闭钩子。可以用下面的代码验证一下,主程序和这些钩子线程是不是运行在一个JVM中:
- public static void main(String[] args) {
- Runtime.getRuntime().addShutdownHook(new Thread(){
- @Override
- public void run() {
- System.out.println("I am still alive!");
- try {
- Thread.currentThread().sleep(1000);
- System.out.println(Runtime.getRuntime().toString());
- System.out.println(Runtime.getRuntime().hashCode());
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- });
- try {
- Thread.currentThread().sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.out.println(Runtime.getRuntime().toString());
- System.out.println(Runtime.getRuntime().hashCode());
- System.out.println("I am exit!");
- }
public static void main(String[] args) {Runtime.getRuntime().addShutdownHook(new Thread(){@Overridepublic void run() {System.out.println("I am still alive!");try {Thread.currentThread().sleep(1000);System.out.println(Runtime.getRuntime().toString());System.out.println(Runtime.getRuntime().hashCode());} catch (InterruptedException e) {e.printStackTrace();}}});try {Thread.currentThread().sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Runtime.getRuntime().toString());System.out.println(Runtime.getRuntime().hashCode());System.out.println("I am exit!");}
主程序中打印出的Runtime的对象的信息和钩子线程中打印出的Runtime的信息是一致的。
下面开始正式的翻译:
Runtime#addShutDownHook方法会注册一个新的 虚拟机关闭钩子;
Java虚拟机只在响应下面两种事件时关闭:
1.当最后的非守护进程结束时,程序正常结束;或者当exit方法(统称,比如System.exit()方法)被调用时
2.JVM响应用户的中断操作,例如键入了^C或者一个系统级的事件,例如用户退出登录或者系统(JVM所在的系统,比如PC的操作系统,Android)关闭。
一个关闭钩子是一个简单初始化还没有启动的线程。当虚拟机开始进入关闭阶段时,虚拟机将以不确定的顺序启动所有已经注册的关闭钩子,当所有的钩子线程结束时,如果finalization-on-exit 启用,JVM将接着运行所有还没被调用的finalizer。最后,虚拟机停止。注意,在JVM的关闭阶段,守护线程将持续运行,如果JVM的关闭阶段是通过调用exit方法进入的,非守护的线程也会在JVM的关闭阶段持续运行。
一旦进入关闭工序,JVM将只能通过调用halt方法停止,这个方法将强制结束虚拟机。
一旦关闭工序开始,虚拟机不能再被注册新的ShutDown hook,也不能撤销之前注册的钩子。这两个操作都会导致抛出一个IllegalStateException错误。
ShutDown钩子运行在Java虚拟机整个生命周期的一个很微妙的时刻,虚拟机生命周期的最后阶段,因此在编写程序时应该十分小心。这些钩子线程应该都是线程安全的,并且要避免任何可能的死锁的发生。钩子线程不应该依赖于绑定的服务,这些绑定的服务包括,注册到虚拟机的其他的钩子线程和在JVM已经开启关闭工序时钩子线程自己。使用其他基于线程的服务,像AWT的事件分发线程,可能导致死锁。
关闭钩子线程中未捕获的错误的处理方式跟其他的线程一样,通过调用ThreadGroup#uncaughtException方法,这个方法的默认实现是打印错误堆栈信息(System#err),然后结束线程;这个方法不会导致虚拟机结束或终止。
在罕见的情况下,虚拟机可能会abort,也就是说,没有干净的关闭而直接停止运行。这种情况会发生在当虚拟机被外部的力量结束时。例如,Unix中的SIGKILL信号或者window平台中的TerminateProcess被调用。虚拟机也可能在一个native的方法出错时abort,例如,毁坏的内部数据结构或者尝试访问不存在的内存。如果虚拟机abort,将不能保证关闭钩子线程被完整运行。
上边这一段是Runtime#addShutDownHook方法的注释。简单总结一下,钩子线程的启动时机:
1.虚拟机自己结束时会调用,比如程序运行完成,或者用户跟虚拟机交互之后,虚拟机接收到退出信号,自己结束
2.外部力量结束虚拟机时,不能保证钩子线程启动,比如在windows平台中,启动任务管理器,直接将这个Java虚拟机关闭进程,这种情况下不能保证钩子线程一定会被调用
JAVA Runtime.addShutdownHook()方法{拿到线程句柄,在程序关闭之前调用释放资源}相关推荐
- Java Thead.interrupt 方法没有使线程停止工作
有问题的interrupt package com.xinyu.test;public class TestInterrupt {public static void main(String[] ar ...
- c++ 多线程:线程句柄可以提前关闭,但是线程并没有关闭
很多程序在创建线程都这样写的: ThreadHandle = CreateThread(NULL,0,.....); CloseHandel(ThreadHandle ); 1,线程和线程句柄(Han ...
- Java关闭挂钩– Runtime.addShutdownHook()
Java shutdown hook are handy to run some code when program exit. We can use java.lang.Runtime.addShu ...
- Java Runtime.exec()的使用
Sun的doc里其实说明还有其他的用法: exec(String[] cmdarray, String[] envp, File dir)Executes the specified command ...
- Java并发编程:如何创建线程?
在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识,然后再阐述如何创建线程以及如何创建 ...
- Java:使用Executors创建和管理线程
http://zhangjunhd.blog.51cto.com/113473/70068/ 1. 类 Executors 此类中提供的一些方法有: 1.1 public static Executo ...
- java条件执行方法_java 开启多线程里面如何加条件判断执行其他逻辑?
方法1:通过Thread类中的isAlive()方法判断线程是否处于活动状态. 线程启动后,只要没有运行完毕,都会返回true. [注]如果只是要等其他线程运行结束之后再继续操作,可以执行t.join ...
- Java——多线程之方法详解
Java多线程系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多 ...
- NDK开发 - C/C++ 访问 Java 变量和方法
上一篇有提到 JNI 访问引用数组,涉及了 C/C++ 访问 Java 实例的方法和变量.虽然在之前的开发中,并没有用到 C/C++ 范围 Java 层数据,但是这部分内容还是很有用的. 传送门:ND ...
- java 销毁线程_线程 学习教程(一): Java中终止(销毁)线程的方法
结束线程有以下三种方法: (1)设置退出标志,使线程正常退出,也就是当run()方法完成后线程终止 (2)使用interrupt()方法中断线程 (3)使用stop方法强行终止线程(不推荐使用,Thr ...
最新文章
- 计算机工程 文章没有创新,【计算机基础论文】小议计算机专业人才创新力的培育(共1911字)...
- PHP中的随机性——你觉得自己幸运吗?
- 安装Ubuntu 18.04后的一些操作
- matlab repmat()
- Javascript设计模式
- C语言写出生命游戏什么水平,我也来汇报~~~生命游戏。
- 马上开课 | 第 3 期临床基因组家系分析,助力发表Case Report
- php 扩展加载顺序,关于PHP中extension加载顺序问题的解决方法
- C的|、||、、、异或、~、!运算
- 智慧交通day02-车流量检测实现13:基于虚拟线圈法的车辆统计+视频中的车流量统计原理解析
- 用计算机分析卫星云图 进行实时天气,卫星云图,气象卫星云图,卫星云图高清实时滚动播放 - 围观天气...
- 27家金融类央企(中投+3政策性银行+5国有银行+中信+光大+4保险集团)(4大资产管理+建银+再保险+保险保障+中诚信托+中央国债+银行金融+科技证券+证券基金)
- 详解 VOC 数据集
- 格林威治时间转北京时间
- c语言竖线什么意思,竖线符号意思
- LG-P3939 数颜色
- golang实现稀疏数组(Sparse array)
- 用Jquey实现双击图片放大和触摸放大的功能。
- 团队里来了个阿里技术大神!架构师都跪了,没有不服的......
- 毕业生关于签约、毁约和存档的介绍---一个很好的科普