Runtime#addShutDownHook方法是给虚拟机增加一个虚拟机关闭时的调用钩子,在虚拟机关闭的时候调用这些钩子线程。还是非常有用的一个方法,最直接的用法就是监控了,因为其是在虚拟机临关闭时被调用,所以天生可以记录虚拟机关闭这件事情,及其相关的信息;再就是清理资源什么的,也可以做一个钩子线程,这样就不用再应用中为这些清理资源的操作找合适的位置了;

下面先翻译一下这个方法的Java doc,在网上找到几篇翻译,都出自一个版本,错误挺多的,这里重新翻译一下:

doc的第一句话是Registers a new virtual-machine shutdown hook.网上的翻译的版本将其翻译成了注册一个新的虚拟机来关闭钩子,这样翻译从语法的角度来讲就是不对的嘛,一句话里Register和Shutdown都成了动词。很简单的一句话,就是注册一个新的虚拟机关闭钩子。可以用下面的代码验证一下,主程序和这些钩子线程是不是运行在一个JVM中:

  1. public static void main(String[] args) {
  2. Runtime.getRuntime().addShutdownHook(new Thread(){
  3. @Override
  4. public void run() {
  5. System.out.println("I am still alive!");
  6. try {
  7. Thread.currentThread().sleep(1000);
  8. System.out.println(Runtime.getRuntime().toString());
  9. System.out.println(Runtime.getRuntime().hashCode());
  10. } catch (InterruptedException e) {
  11. e.printStackTrace();
  12. }
  13. }
  14. });
  15. try {
  16. Thread.currentThread().sleep(1000);
  17. } catch (InterruptedException e) {
  18. // TODO Auto-generated catch block
  19. e.printStackTrace();
  20. }
  21. System.out.println(Runtime.getRuntime().toString());
  22. System.out.println(Runtime.getRuntime().hashCode());
  23. System.out.println("I am exit!");
  24. }

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虚拟机关闭进程,这种情况下不能保证钩子线程一定会被调用

上边的1和2都可以通过稍微修改下最上边的程序验证。

JAVA Runtime.addShutdownHook()方法{拿到线程句柄,在程序关闭之前调用释放资源}相关推荐

  1. Java Thead.interrupt 方法没有使线程停止工作

    有问题的interrupt package com.xinyu.test;public class TestInterrupt {public static void main(String[] ar ...

  2. c++ 多线程:线程句柄可以提前关闭,但是线程并没有关闭

    很多程序在创建线程都这样写的: ThreadHandle = CreateThread(NULL,0,.....); CloseHandel(ThreadHandle ); 1,线程和线程句柄(Han ...

  3. Java关闭挂钩– Runtime.addShutdownHook()

    Java shutdown hook are handy to run some code when program exit. We can use java.lang.Runtime.addShu ...

  4. Java Runtime.exec()的使用

    Sun的doc里其实说明还有其他的用法: exec(String[] cmdarray, String[] envp, File dir)Executes the specified command ...

  5. Java并发编程:如何创建线程?

    在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识,然后再阐述如何创建线程以及如何创建 ...

  6. Java:使用Executors创建和管理线程

    http://zhangjunhd.blog.51cto.com/113473/70068/ 1. 类 Executors 此类中提供的一些方法有: 1.1 public static Executo ...

  7. java条件执行方法_java 开启多线程里面如何加条件判断执行其他逻辑?

    方法1:通过Thread类中的isAlive()方法判断线程是否处于活动状态. 线程启动后,只要没有运行完毕,都会返回true. [注]如果只是要等其他线程运行结束之后再继续操作,可以执行t.join ...

  8. Java——多线程之方法详解

    Java多线程系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多 ...

  9. NDK开发 - C/C++ 访问 Java 变量和方法

    上一篇有提到 JNI 访问引用数组,涉及了 C/C++ 访问 Java 实例的方法和变量.虽然在之前的开发中,并没有用到 C/C++ 范围 Java 层数据,但是这部分内容还是很有用的. 传送门:ND ...

  10. java 销毁线程_线程 学习教程(一): Java中终止(销毁)线程的方法

    结束线程有以下三种方法: (1)设置退出标志,使线程正常退出,也就是当run()方法完成后线程终止 (2)使用interrupt()方法中断线程 (3)使用stop方法强行终止线程(不推荐使用,Thr ...

最新文章

  1. 计算机工程 文章没有创新,【计算机基础论文】小议计算机专业人才创新力的培育(共1911字)...
  2. PHP中的随机性——你觉得自己幸运吗?
  3. 安装Ubuntu 18.04后的一些操作
  4. matlab repmat()
  5. Javascript设计模式
  6. C语言写出生命游戏什么水平,我也来汇报~~~生命游戏。
  7. 马上开课 | 第 3 期临床基因组家系分析,助力发表Case Report
  8. php 扩展加载顺序,关于PHP中extension加载顺序问题的解决方法
  9. C的|、||、、、异或、~、!运算
  10. 智慧交通day02-车流量检测实现13:基于虚拟线圈法的车辆统计+视频中的车流量统计原理解析
  11. 用计算机分析卫星云图 进行实时天气,卫星云图,气象卫星云图,卫星云图高清实时滚动播放 - 围观天气...
  12. 27家金融类央企(中投+3政策性银行+5国有银行+中信+光大+4保险集团)(4大资产管理+建银+再保险+保险保障+中诚信托+中央国债+银行金融+科技证券+证券基金)
  13. 详解 VOC 数据集
  14. 格林威治时间转北京时间
  15. c语言竖线什么意思,竖线符号意思
  16. LG-P3939 数颜色
  17. golang实现稀疏数组(Sparse array)
  18. 用Jquey实现双击图片放大和触摸放大的功能。
  19. 团队里来了个阿里技术大神!架构师都跪了,没有不服的......
  20. 毕业生关于签约、毁约和存档的介绍---一个很好的科普

热门文章

  1. 学习用MaxScipt批处理Max文件
  2. 搜索引擎选择: Elasticsearch与Solr(转载)
  3. BZOJ 1067 降雨量(RMQ-ST+有毒的分类讨论)
  4. 错题分析--ASP.NET
  5. C程序之修改Windows的控制台颜色(转载)
  6. 前台实现ajax 需注意的地方
  7. 条件随机场 Conditional Random Fields
  8. 今天解决了首页无头像被显示的问题
  9. 【转】在birt中显示条形码
  10. 使用canvas上传图片+上传进度