Runtime.addShutdownHook()(译)
序言:
每一个Java程序都可以为JVM增加一个关闭钩子。JVM将在关闭之前执行关闭钩子中的指令。
问题:
一个程序可能需要在退出前执行一些指令。程序可能由于下列原因而退出:
所有的线程已经执行完毕
调用System.exit()
用户输入Ctrl+C
系统级关闭或用户注销
适用场景:
保存应用状态,例如,当多数IDE退出时,它们将记忆最后的视图有哪些。
关闭某些数据库连接。
将应用关闭的消息发送给系统管理员。
解决方案:
关闭钩子支持所有这些场景。应用可以增加一个关闭钩子,JVM将在应用退出时调用它。
抽象层次的概念:
将所有的指令(Java代码)写入一个线程的run()内,并且调用java.lang.Runtime.addShutdownHook(Thread t)。该方法将这个线程注册为JVM的关闭钩子。在关闭JVM的时候,JVM将并行地运行这些钩子(线程将在JVM关闭的时候启动)。
代码示例:
public class AddShutdownHookSample {
public void attachShutDownHook() {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.out.println("Inside Add Shutdown Hook");
}
});
System.out.println("Shut Down Hook Attached.");
}
public static void main(String[] args) {
AddShutdownHookSample sample = new AddShutdownHookSample();
sample.attachShutDownHook();
System.out.println("Last instruction of Program....");
System.exit(0);
}
}
输出:
Shut Down Hook Attached. Last instruction of Program.... Inside Add Shutdown Hook
现在明白了如何使用addShutDownHook。如果需要可以增加多个关闭钩子,但是需要注意的是,钩子是并行地运行,所以注意并发避免死锁发生。
在应用中实现关闭钩子:
关闭钩子的数量:关闭钩子的数量没有限制,如果需要可以增加多个关闭钩子。看看run()的修改版本:
public void attachShutDownHook() {
for (int i = 0; i < 10; i++) {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.out.println("Inside Add Shutdown Hook : "
+ Thread.currentThread().getName());
}
});
}
}
如上,我们增加了10个关闭钩子。
何时增加关闭钩子:任何时候!!!在任何情况下都可以增加一个关闭钩子,只要在JVM关闭之前。如果试图在JVM开始关闭后注册一个关闭钩子,将抛出一个带有”Shutdown is progress”消息的IllegalStateException。
增加相同的钩子:不能增加相同的钩子。如果这样做了,将抛出带有”Hook previously registered”消息的IllegalArgumentException。
注销钩子:调用Runtime.removeShutdownShook(Thread hook)可以注销一个钩子。
注意:大多数时候,使用匿名内部类来注册关闭钩子,既然我们没有持有这些类的可用引用,我们也无法使用要注销钩子的匿名内部类,因为我们需要将它们传递给removeShutdownHook(Thread hook)。
注意并发:万一不止一个关闭钩子,它们将并行地运行,并容易引发线程问题,例如死锁。Java Doc对该方法是这样描述的: /**
* A <i>shutdown hook</i> is simply an initialized but unstarted thread.
* When the virtual machine begins its shutdown sequence it will start all
* registered shutdown hooks in some unspecified order and let them run
* concurrently. When all the hooks have finished it will then run all
* uninvoked finalizers if finalization-on-exit has been enabled. Finally,
* the virtual machine will halt. Note that daemon threads will continue to
* run during the shutdown sequence, as will non-daemon threads if shutdown
* was initiated by invoking the <tt>{@link #exit exit}</tt> method.
*/
翻译过来:
关闭钩子只是一个已初始化但尚未启动的线程。虚拟机开始启用其关闭序列时,它会以某种未指定的顺序启动所有已注册的关闭钩子,并让它们同时运行。运行完所有的钩子后,如果已启用finalization-on-exit,那么虚拟机接着会运行所有未调用的finalizers。最后,虚拟机会暂停。注意,关闭序列期间会继续运行守护线程,如果通过调用exit方法来发起关闭序列,那么也会继续运行非守护线程。
关闭钩子的可靠性:JVM将在退出的时候尽最大努力来执行关闭钩子,但是不保证一定会执行。例如,当在Linux中使用-kill命令时,或在Windows中终结进程时,由于本地代码被调用,JVM将立即退出或崩溃。
注意钩子的时间消耗:需要注意的重点之一是,关闭钩子不应该花费过多时间。考虑这样一个场景,当用户从操作系统中注销,操作系统花费非常有限的时间就正常退出了,因此在这样样的场景下JVM也应该尽快退出。
结论:
Runtime.addShutdownHook(Thread hook)是非常方便的工具,它提供从JVM中优雅退出的一个通用机制。尤其是在类似服务器实现这样的大型应用中。当然,应该小心使用。
参考:
http://download.oracle.com/javase/1.5.0/docs/guide/lang/hook-design.html
原文地址:http://hellotojavaworld.blogspot.com/2010/11/runtimeaddshutdownhook.html
Runtime.addShutdownHook()(译)的更多相关文章
- 利用 java.lang.Runtime.addShutdownHook() 钩子程序,保证java程序安全退出
以前在开发时只知道依靠数据库事务来保证程序关闭时数据的完整性. 但有些时候一个业务上要求的原子操作,不一定只包括数据库,比如外部接口或者消息队列.此时数据库事务就无能为力了. 这时我们可以依靠java ...
- Runtime.addShutdownHook的用法
原文出处:http://kim-miao.iteye.com/blog/1662550.感谢作者的无私分享. 一.Runtime.addShutdownHook理解 在看别人的代码时,发现其中有这个方 ...
- Runtime.addShutdownHook用法
一.什么是ShutdownHook? 在Java程序中可以通过添加关闭钩子,实现在程序退出时关闭资源.平滑退出的功能. 使用Runtime.addShutdownHook(Thread hook)方法 ...
- 关于jvm钩子 Runtime.getRuntime().addShutdownHook
转自: http://www.cnblogs.com/nexiyi/p/java_add_ShutdownHook.html 在线上Java程序中经常遇到进程程挂掉,一些状态没有正确的保存下来,这时候 ...
- Java Runtime 详解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt219 那就首先说点Runtime类吧,他是一个与JVM运行时环境有关的类,这 ...
- Java Runtime.exec()的使用
Sun的doc里其实说明还有其他的用法: exec(String[] cmdarray, String[] envp, File dir) Executes the specified command ...
- [转]Java中Runtime.exec的一些事
0 预备知识 1 不正确的调用exitValue 2不正确的调用waitFor 3 一种可接受的调用方式 4 调用认为是可执行程序的时候容易发生的错误 5 window执行的良好示例 6 不良好的重定 ...
- Runtime.getRuntime()
1转自:https://www.aliyun.com/jiaocheng/849282.html 那就首先说点Runtime类吧,他是一个与JVM运行时环境有关的类,这个类是Singleton的.我说 ...
- Java Runtime.exec()用法
转自:https://www.cnblogs.com/mingforyou/p/3551199.html Java Runtime.exec()的使用 Sun的doc里其实说明还有其他的用法: exe ...
随机推荐
- flink Transitive Closure算法,实现寻找新的可达路径
flink 使用Transitive Closure算法实现可达路径查找. 1.Transitive Closure是翻译闭包传递?我觉得直译不准确,意译应该是传递特性直至特性关闭,也符合本例中传递路 ...
- ZigBee究竟是什么?有什么用?
ZigBee技术是一种近距离.低复杂度.低功耗.低速率.低成本的双向无线通讯技术.主要用于距离短.功耗低且传输速率不高的各种电子设备之间进行数据传输以及典型的有周期性数据.间歇性数据和低反应时间数据传 ...
- ajax的jQuery的表单序列化获取参数serialize()
需要引入jQuery.js才能使用$("form表单的id").serialize()可获取form表单里面所有表单元素的值和name属性值,按顺序拼接成查询字符串格式为name值 ...
- error: exportArchive: The data couldn’t be read because it isn’t in the correct format.
在执行ios 打包的时候,我们通过执行下面的指令来打包ipa: mkdir arch archive_path=arch/${app_name}.xcarchive workspace_name=HP ...
- CMS收集器和G1收集器 他们的优缺点对比 G1只有并发标记才不会stop-the-world 其他都会停下来(阿里多次问到)
CMS收集算法 参考:图解 CMS 垃圾回收机制原理,-阿里面试题 G1收集算法 参考:G1 垃圾收集器入门 首先要知道 Stop the world的含义(网易面试):不管选择哪种GC算法,stop ...
- html 后手
1.a (1.)超链接 <a href="new.html">点击进入到新网页</a>这里可以直接跳转到一个页面 <a href="http ...
- python预科前三天:计算器知识、Python下载和安装、Pycharm下载安装激活设置、解释型和编译型、git、思维导图、显示隐藏文件、隐藏已知文件扩展名、创建组织、创建项目、提交作业、排BUG技巧
1.计算机组成结构:CPU.硬盘.内存.输入输出设备.主板.电源. 2.硬件之间的协作关系:是CPU运算完后给操作系统.专业术语叫指令. 3.键盘输入a之后发生的事情:键盘-CPU-操作系统-显卡-显 ...
- 网络yum源配置
系统环境:CentOS7 [1] 首先备份/etc/yum.repos.d/CentOS-Base.repo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum ...
- z+f数据解析
1.先打开cmd2.把D:\qcc\编译和解析\debug_jiexi\SampleZFS.exe 拉进来.3.SampleZFS.exe -i *.zfs -o D:\*.txt 注意:*号代表文件 ...
- How to display `top` results sorted by memory usage in real time?
If you're using the top that comes with Ubuntu (top -v = procps-ng version 3.3.10), then you can use ...