原文出处:http://kim-miao.iteye.com/blog/1662550。感谢作者的无私分享。

一.Runtime.addShutdownHook理解

在看别人的代码时,发现其中有这个方法,便顺便梳理一下。

void java.lang.Runtime.addShutdownHook(Thread hook)

该方法用来在jvm中增加一个关闭的钩子。当程序正常退出,系统调用 System.exit方法或虚拟机被关闭时才会执行添加的shutdownHook线程。其中shutdownHook是一个已初始化但并不有启动的线程,当jvm关闭的时候,会执行系统中已经设置的所有通过方法addShutdownHook添加的钩子,当系统执行完这些钩子后,jvm才会关闭。所以可通过这些钩子在jvm关闭的时候进行内存清理、资源回收等工作。

二.示例代码

  1. public class TestRuntimeShutdownHook {
  2. public static void main(String[] args) {
  3. Thread shutdownHookOne = new Thread() {
  4. public void run() {
  5. System.out.println("shutdownHook one...");
  6. }
  7. };
  8. Runtime.getRuntime().addShutdownHook(shutdownHookOne);
  9. Runnable threadOne = new Runnable() {
  10. public void run() {
  11. try {
  12. Thread.sleep(1000);
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. }
  16. System.out.println("thread one doing something...");
  17. }
  18. };
  19. Runnable threadTwo = new Thread() {
  20. public void run() {
  21. try {
  22. Thread.sleep(2000);
  23. } catch (InterruptedException e) {
  24. e.printStackTrace();
  25. }
  26. System.out.println("thread two doing something...");
  27. }
  28. };
  29. threadOne.run();
  30. threadTwo.run();
  31. }
  32. }

输出如下:

  1. thread one doing something...
  2. thread two doing something...
  3. shutdownHook one...

我在这里附上JDK api上关于这个方法的说明,看这个api觉得有点绕。

=========================================================================================================

addShutdownHook

public void addShutdownHook(Thread hook)
注册新的虚拟机来关闭钩子。

Java 虚拟机会为了响应以下两类事件而关闭

  • 程序正常退出,这发生在最后的非守护线程退出时,或者在调用 exit(等同于 System.exit)方法时。或者,
  • 为响应用户中断而终止 虚拟机,如键入 ^C;或发生系统事件,比如用户注销或系统关闭。

关闭钩子 只是一个已初始化但尚未启动的线程。虚拟机开始启用其关闭序列时,它会以某种未指定的顺序启动所有已注册的关闭钩子,并让它们同时运行。运行完所有的钩子后,如果已启用退出终结,那么虚拟机接着会运行所有未调用的终结方法。最后,虚拟机会暂停。注意,关闭序列期间会继续运行守护线程,如果通过调用 exit 方法来发起关闭序列,那么也会继续运行非守护线程。

一旦开始了关闭序列,则只能通过调用 halt 方法来停止这个序列,此方法可强行终止虚拟机。

一旦开始了关闭序列,则不可能注册新的关闭钩子或取消注册先前已注册的钩子。尝试执行这些操作会导致抛出 IllegalStateException

关闭钩子可在虚拟机生命周期中的特定时间运行,因此应保护性地对其进行编码。特别是应将关闭钩子编写为线程安全的,并尽可能地避免死锁。关闭钩子还应该不盲目地依靠某些服务,这些服务可能已注册了自己的关闭钩子,所以其本身可能正处于关闭进程中。例如,试图使用其他基于线程的服务(如 AWT 事件指派线程)可能导致死锁。

关闭钩子应该快速地完成其工作。当程序调用 exit 时,虚拟机应该迅速地关闭并退出。由于用户注销或系统关闭而终止虚拟机时,底层的操作系统可能只允许在固定的时间内关闭并退出。因此在关闭钩子中尝试进行任何用户交互或执行长时间的计算都是不明智的。

与其他所有线程一样,通过调用线程 ThreadGroup 对象的 uncaughtException 方法,可在关闭钩子中处理未捕获的异常。此方法的默认实现是将该异常的堆栈跟踪打印至 System.err 并终止线程;它不会导致虚拟机退出或暂停。

仅在很少的情况下,虚拟机可能会中止,也就是没有完全关闭就停止运行。虚拟机被外部终止时会出现这种现象,比如在 Unix 上使用 SIGKILL 信号或者在 Microsoft Windows 上调用 TerminateProcess。如果由于内部数据结构损坏或试图访问不存在的内存而导致本机方法执行错误,那么可能也会中止虚拟机。如果虚拟机中止,则无法保证是否将运行关闭钩子。

参数:
hook - 一个已初始化但尚未启动的 Thread 对象
抛出:
IllegalArgumentException - 如果指定的钩子已注册,或者可以确定钩子正在运行或者已运行完毕
IllegalStateException - 如果虚拟机已经处于关闭进程中
SecurityException - 如果安全管理器存在并且拒绝 RuntimePermission("shutdownHooks")

Runtime.addShutdownHook的用法的更多相关文章

  1. Runtime.addShutdownHook用法

    一.什么是ShutdownHook? 在Java程序中可以通过添加关闭钩子,实现在程序退出时关闭资源.平滑退出的功能. 使用Runtime.addShutdownHook(Thread hook)方法 ...

  2. RunTime的一些用法

    RunTime的一些用法   RunTime简介 RunTime简称运行时.OC就是运行时机制,其中最主要的是消息机制 对于OC来说,在编译的时候并不能决定真正调用哪个函数,只有真正运行时才会根据函数 ...

  3. 利用 java.lang.Runtime.addShutdownHook() 钩子程序,保证java程序安全退出

    以前在开发时只知道依靠数据库事务来保证程序关闭时数据的完整性. 但有些时候一个业务上要求的原子操作,不一定只包括数据库,比如外部接口或者消息队列.此时数据库事务就无能为力了. 这时我们可以依靠java ...

  4. Runtime.addShutdownHook()(译)

    序言: 每一个Java程序都可以为JVM增加一个关闭钩子.JVM将在关闭之前执行关闭钩子中的指令. 问题: 一个程序可能需要在退出前执行一些指令.程序可能由于下列原因而退出: 所有的线程已经执行完毕 ...

  5. RunTime.getRunTime().addShutdownHook的用法

    今天在阅读Tomcat源码的时候,catalina这个类中使用了下边的代码,不是很了解,所以google了一下,然后测试下方法,Tomcat中的相关代码如下: Runtime.getRuntime() ...

  6. addShutdownHook的用法

    addShutdownHook作为一个正常关闭Java程序的途径,其实是非常有用的. 有JDK文档可知,当程序正常退出,或者为响应用户中断而终止虚拟机的时候,就会调用里面的线程,来作最后的退出处理. ...

  7. Runtime 10种用法

    来源:haojingxue_iOS 链接:http://www.jianshu.com/p/3182646001d1 阅读了多篇运行时的文章,感觉都很不错,从几篇文章里面提取一些个人认为比较重要的,偏 ...

  8. Java Runtime.exec()用法

    转自:https://www.cnblogs.com/mingforyou/p/3551199.html Java Runtime.exec()的使用 Sun的doc里其实说明还有其他的用法: exe ...

  9. 关于jvm钩子 Runtime.getRuntime().addShutdownHook

    转自: http://www.cnblogs.com/nexiyi/p/java_add_ShutdownHook.html 在线上Java程序中经常遇到进程程挂掉,一些状态没有正确的保存下来,这时候 ...

随机推荐

  1. http协议【转】

    HTTP协议详解 当今web程序的开发技术真是百家争鸣,ASP.NET, PHP, JSP,Perl, AJAX 等等. 无论Web技术在未来如何发展,理解Web程序之间通信的基本协议相当重要, 因为 ...

  2. append和extend 的区别

    l = ["zhy",666] l.extend(["edit","sdd"]) print(l) #['zhy', 666, 'edit' ...

  3. 【转载】Linux下的IO监控与分析

    近期要在公司内部做个Linux IO方面的培训, 整理下手头的资料给大家分享下 各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performance and Tuning G ...

  4. Linux基本操作笔记

    1.Linux是一个统称,内核是一致的.分为Linux系统管理员和Linux程序员包括管理和软件开发. 2.要掌握Linux,有四步,第一,在Linux平台上的开发,比如,vi.gcc.gdb等和Li ...

  5. iOS QQ分享图片无反应问题

    受iOS 9 上 http 限制 需要在info.plist文件添加必要string <key>LSApplicationQueriesSchemes</key> <ar ...

  6. 12、ABPZero系列教程之拼多多卖家工具 拼团提醒功能登录拼多多实现

    上篇文章已经完成了整个拼多多拼团提醒功能,本篇继续完成拼多多帐号登录,拼多多帐号登录的目的是为了获取拼团商品的SKU和订单号,便于商家备货. 以下是拼多多官方的后台登录,要实现的功能并不是直接在这里登 ...

  7. c#的托管代码和非托管代码的理解

    理解托管和非托管代码的前提之下,要先了解CLR(公共语言运行库) .Net Framework 是由彼此独立又相关的两部分组成:CLR 和 类库, CLR是它为我们提供的服务,类库是它实现的功能. . ...

  8. Django模板中的数字自增

    Django框架的模板提供了{% for %} 标签来进行循环 例如对集合进行循环是比较简单的 {% for row in v1 %} <div>{{row.name}}</div& ...

  9. hdu 5919--Sequence II(主席树--求区间不同数个数+区间第k大)

    题目链接 Problem Description Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2 ...

  10. 【Html5】-- 塔台管制

    想做这个游戏已久,今天终于初步完成,先解释下,这是一个模拟机场塔台管制指挥的游戏,飞机从不同的方向飞入管制空域,有不同的目的地,飞机名称最后一个字母表示飞机要到达的目的地,分ABCD和R.A-D表示四 ...