我有一个应该在unix下永远运行的项目。但是如果我们需要阻止它,我正在考虑编写一个终止程序来优雅地关闭它。 我没有写这种程序的经验。 有谁能请给我一些提示。在java中有任何信号捕获方案吗? 谢谢
答案 0 :(得分:2)
您需要为应用程序添加一个关闭钩子。这是一个线程,它将在程序正常退出时启动,或者如果JVM因响应用户中断,SIGTERM信号或系统范围事件(例如用户注销或系统关闭)而终止。有关详细信息,请查看javadocs。
以下是创建关闭挂钩时涉及的步骤:
1)创建关闭钩子类:
public class AppShutdownHook extends Thread{
public void run(){
logger.info("Running shutdown hook...") ;
//cleanup e.g. close database connections etc
}
}
2)注册关闭钩子:
public class App{
public App(){
Runtime.getRuntime().addShutdownHook(new AppShutdownHook()) ;
}
}
这种方法的优点在于,您没有特殊的“停止脚本”,每次必须停止应用程序或重新启动计算机时都需要记住该脚本。
答案 1 :(得分:1)
这里有几个选项。
一个是你可以让它接受命令行输入,但这需要你可以访问它的输入流,如果你关闭终端等可能不会发生。可能最好的方法是使用它们一个套接字,让它监听一个特定的流,以便关闭。然后,您的终止程序将负责写入该套接字。
另一种选择是使用某种更复杂的IPC,如共享内存。
最后,另一个选择是使用存储在系统某处的平面文件,您的进程将监视其中的更改。然后终止程序将写入该文件。
答案 2 :(得分:0)
我记得很久以前被问到similar question。一种可能的做法是使用SignalHandler。
您可以阅读full article here。它似乎与IBM JVM有关,但我认为它对Java Hotspot同样有效。
Java的一个鲜为人知的特征就是 应用程序安装的能力 它自己的信号处理程序 通过sun.misc.Signal支持 类。但是,使用时要小心 来自sun.misc包的类 因为它包含无证件 支持可能会改变的类 Java版本之间。您可以 为任何信号安装Java处理程序 JVM没有使用它。这些 信号处理程序与本机类似 处理程序,因为它们是在调用时调用的 引发本机系统信号,但是 它们将始终作为单独的运行 Java线程。基本上,当一个 提出了一个Java的信号 信号处理程序是可用的,JVM的 “信号调度员线程”被唤醒 并告知信号。信号 然后调度程序线程调用Java 创建和启动新方法 已安装的Java信号的线程 处理程序。写一个Java信号 handler,定义一个类 实现sun.misc.SignalHandler 接口并注册处理程序 使用sun.misc.Signal.handle() 方法
我还参与了有关主题here
的讨论答案 3 :(得分:0)
可以在java中进行信号处理,但它是一个依赖于使用sun.misc。*类的功能,因为它们被认为是内部类,并且在版本之间会发生变化,因此需要谨慎使用。
有了这个警告,请查看此链接以获取更多信息:http://www.ibm.com/developerworks/ibm/library/i-signalhandling/#N102C8
本文基于java 1.3.1,但该机制仍然存在于sun和ibm 1.6 jvms中。
我也想知道是否可以使用jni和agentlib在你的jvm中安装本机信号处理程序...我从来没有尝试过,而且必须调查它。 jvm可能已经有了无法覆盖的信号处理。