Java虚拟机ShutdownHooks
来源:互联网 发布:英语离线翻译软件 编辑:程序博客网 时间:2024/06/17 04:17
Java虚拟机为开发人员提供了一个回调入口,开发人员通过这个回调入口,向Java虚拟机注册任意一段代码,让Java虚拟机在将要结束运行之前,执行这段代码。这个机制通常被用来做一些资源的清理工作,tomcat容器源码中就有用到这个机制,现在对这个机制做一个介绍。
demo
public static void main(String[] args) { Runtime.getRuntime().addShutdownHook(new Thread(){ @Override public void run() { System.out.println("The hook is executing"); } }); System.out.println("The application is going to be stopped");}
但是使用Shutdown Hook时,会有一些注意的地方:
在某些情况下向JVM注册的hooks不会被执行
JVM并不保证这些hooks一定会被执行,hooks是否会被执行受系统内部及外部因素影响。- JVM遇到严重的内部错误的时候
- 用户通过操作系统向Java虚拟机进程发送SIGKILL,要求操作系统立即停止虚拟机进程时
- 调用
Runtime.halt()
停止虚拟机执行
只有当JVM正常退出时,hooks才会被执行,应用程序抛出的运行时异常,以及JVM抛出的错误(Error)不会影响hook的执行。
Shutdown Hook处于执行状态时,仍有可能被强制停止
一旦hooks启动之后,仍然可能由于各种原因被停止,需要注意的是,不能在hooks中进行一些非常耗时的操作,以及资源申请操作,因为这样会造成严重问题,如死锁(JVM不会保证hooks的执行顺序,如果hooks中的代码缺少足够的同步,会造成死锁,及不一致)- JVM不保证Shutdown Hooks的执行顺序
- Shutdown Hooks一旦开始执行,只能通过
Runtime.halt()
命令来停止hooks的执行,调用System.exit()
并不能停止hooks的执行 - 如果Shutdown Hook中抛出了异常,并且没有被捕获,那么JVM会使用default exception handler来处理异常
tomcat中Shutdown hook的应用
tomcat在启动容器之后,会向JVM注册一个Shutdown hook用于确保tomcat应用即使是在异常退出之后,仍然能够保证资源被正确的释放掉,下面是org.apache.catalina.startup.Catalina
类的start()
方法的片段
// Register shutdown hookif (useShutdownHook) { if (shutdownHook == null) { shutdownHook = new CatalinaShutdownHook(); } Runtime.getRuntime().addShutdownHook(shutdownHook); // If JULI is being used, disable JULI's shutdown hook since // shutdown hooks run in parallel and log messages may be lost // if JULI's hook completes before the CatalinaShutdownHook() LogManager logManager = LogManager.getLogManager(); if (logManager instanceof ClassLoaderLogManager) { ((ClassLoaderLogManager) logManager).setUseShutdownHook( false); }}
下面是CatalinaShutdownHook的定义:
protected class CatalinaShutdownHook extends Thread { @Override public void run() { try { if (getServer() != null) { Catalina.this.stop(); } } catch (Throwable ex) { ExceptionUtils.handleThrowable(ex); log.error(sm.getString("catalina.shutdownHookFail"), ex); } finally { // If JULI is used, shut JULI down *after* the server shuts down // so log messages aren't lost LogManager logManager = LogManager.getLogManager(); if (logManager instanceof ClassLoaderLogManager) { ((ClassLoaderLogManager) logManager).shutdown(); } } }}
可以看到tomcat使用Shutdown Hook来确保,Server和LoggerManager正常关闭,为了避免因Server关闭先于LoggerManager导致日志消息丢失的问题,LoggerManager并没有直接使用Shutdown Hook来关闭。
- Java虚拟机ShutdownHooks
- 如何finalize方法和shutdownHooks互动
- Java虚拟机
- Java虚拟机
- Java虚拟机
- Java虚拟机
- Java虚拟机
- Java虚拟机
- Java虚拟机
- Java虚拟机
- Java虚拟机
- Java虚拟机
- JAVA虚拟机
- Java虚拟机
- Java虚拟机
- Java虚拟机
- java虚拟机
- java虚拟机
- 经典排序算法总结与实现
- matlab知识点
- 国内4种常用日内CTA策略介绍及实现
- JavaScript的 !!
- CAS认证(2):认证过程
- Java虚拟机ShutdownHooks
- 《Android 创建线程源码与OOM分析》
- for foreach iterator
- 在JAVA中线程到底起到什么作用!
- UVA
- Github 创建仓库并上传项目
- 第十一周java作业
- 什么是 web 框架?
- Django_静态资源配置