我使用许可的API,它具有获取/从具有许可证的数量有限的许可证服务器释放许可对象的方法。 在我的应用程序开始时,我打电话给获得许可证的方法,但我要确保,如果我的程序终止/崩溃突然(例外,SIGTERM等),这得到释放均匀。 在关闭钩子来处理这个问题的最佳方式是什么?
Answer 1:
@thedan大约是硬JVM崩溃正确。 如果JVM崩溃硬或它得到一个SIGKILL,它不会有机会退出之前运行任何东西。 有什么可以做,在该方案中,以解决这个问题在Java中。 (但是,这种情况在其他语言中也一样......)
但是,如果JVM确实有序关闭响应结束所有非dameon线程调用System.exit(),得到一个SIGINT等等,那么JVM将尝试运行关闭挂钩。 有在Java的关闭挂钩机制的详细信息Q&A页面和javadoc文档 。
在finally
的做法也是一种选择,但仅仅是如果有问题的线程在JVM退出之前结束工作。 如果这将不会发生System.exit()
调用或JVM通过信号终止。 关闭挂钩在更多情况下工作。
(在我看来, finally
是真的在单个线程执行清洁,而不是整个应用程序。但是,如果你的应用程序只包含一个线程的...或者如果它有一个主线程,负责为正常关机...然后finally
可以成为应用清理的目的。)
真正的解决办法是配置许可的API,以便在使用许可应用程序实例消失而不释放它的许可证管理器可以检测到。 这是否可行取决于许可证管理器。
Answer 2:
如果程序是通过JVM的崩溃终止,你不能依赖于任何被调用。
如果方案通过,不涉及JVM异常终止,你应该能够在一个try / catch来包装的一切/ finally块。 finally块中的任何代码将保证代码退出之前运行。
Answer 3:
对于例外情况,你可以用身体main
在try/catch/block
。 对于处理SIGTERM
信号,你可以添加一个关闭挂钩 。 然而,关闭钩子不能保证被触发像的信号SIGKILL
。
从Java文档 :
在极少数情况下,虚拟机可能会中止 ,也就是没有停止干净关停运行。 当虚拟机被外部终止,例如与发生本
SIGKILL
在Unix信号或TerminateProcess
在Microsoft Windows呼叫。 虚拟机也可中止如果本机方法就会出差错通过,例如,破坏内部数据结构或试图访问不存在的存储器。 如果虚拟机然后中止无法保证可以制成任何关闭挂钩是否会运行。
Answer 4:
您可以通过调用从未实现Sytem.exit这个()。 在main()创建一个“最后一道防线”与
try {
startApp();
} catch (Exception ex) {
// do some logging
} finally {
releaseLicense();
}