用户关闭关闭程序,需要做一些善后的清理工作,但问题是,某些用户不会按照推荐的方法关闭应用程序,肯能导致善后工作无法进行。像tomcat调用server的start方法启动容器,然后会逐级调用start。当发出关闭命令是会启动关闭功能,但是关闭可能会有一些意外产生,导致应用程序没有进入到我们制定的关闭方法去。如何解决这个问题呢,使得即使有意外也能正常进入关闭流程。
好在java提供了一种优雅的方式去解决这种问题。使得关闭的善后处理的代码能执行。java的关闭钩子能确保总是执行,无论用户如何终止应用程序。除非用户kill,这个是个死穴。
对java而言,虚拟机会对以下几种操作进行关闭:
(1)系统调用System.exit()方法
(2)程序最后一个守护线程退出时,应用程序正常退出。
(3)用户强行中断程序运行,比如ctrl+c等其他方式中断java程序
关闭钩子的生成:
1.创建Thread的子类
2.实现run方法,应用程序关闭时会调用该方法,不需要调用start方法
3.在应用中实例化关闭钩子类
4.使用Runtime注册关闭钩子
public class ExitHook
{
public static void main(String[] args)
throws IOException
{
final FileOutputStream fos;
fos = new FileOutputStream("a.bin");
System.out.println("程序打开物理资源!");
//为系统注册关闭钩子
Runtime.getRuntime().addShutdownHook(
new Thread()
{
public void run()
{
//使用关闭钩子来关闭资源
if (fos != null)
{
try
{
fos.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
System.out.println("程序关闭了物理资源!");
}
});
System.exit(0);
}
}
关闭钩子,负责在程序退出时回收系统资源,运行上面程序,将看到
系统可以正常关闭物理资源。
建议:同一个JVM最好只使用一个关闭钩子,而不是每个服务都使用一个不同的关闭钩子,使用多个关闭钩子可能会出现当前这个钩子所要依赖的服务可能已经被另外一个关闭钩子关闭了。为了避免这种情况,建议关闭操作在单个线程中串行执行,从而避免了再关闭操作之间出现竞态条件或者死锁等问题。
http://blog.csdn.net/huangmin2050/article/details/7694610
http://blog.sina.com.cn/s/blog_6145ed8101015tbu.html
http://www.cnblogs.com/langtianya/p/4300282.html