2012-01-03 129 views
1

我有一个项目,应该永远在UNIX下运行。但如果我们需要阻止它,我正在考虑编写一个终止程序来优雅地关闭它。 我没有写这种程序的经验。 任何人都可以请给我一些提示。在java中是否有任何信号捕捉方案? 谢谢关于Java终止程序

+1

可能重复的[如何陷入信号在一个Java应用程序初始化使用bash脚本](http://stackoverflow.com/questions/4147288/how-to-trap-a-signal-in-a-java -application-initialized-using-a-bash-script) – hvgotcodes 2012-01-03 17:59:43

回答

1

这里有几个选项。

一个是你可以让它接受命令行输入,但这将需要你有权访问它的输入流,这可能不会发生,如果你关闭终端等。可能最好的方法是使用无论是套接字,并让它监听特定的流,以关闭。您的终止程序将负责写入该套接字。

另一种选择是使用某种更复杂的IPC,如共享内存。

最后,另一种选择是使用存储在系统某处的平面文件,以便您的进程监视更改。终止程序然后将写入该文件。

+0

谢谢!我认为使用套接字是一个好主意! – 2012-01-03 18:06:36

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()) ; 
    } 
} 

的美这种方法是,你没有一个特殊的“停止脚本”,你需要记住每次你必须停止你的应用程序或重新启动你的机器时运行。

参考:Shutting Down Java Apps

0

我想起了similar question被要求的时间前。一种可能的行动方式是使用SignalHandler。您可以阅读full article here。它似乎与IBM JVM有关,但我认为它对于Java Hotspot同样有效。

的Java的一个鲜为人知的功能是安装 自己的信号处理程序,这是 通过sun.misc.Signal 类支持的 能力的应用程序。但是,在使用sun.misc数据包 中的 类时请小心,因为它包含可能在Java发行版之间更改 的未记录的 支持类。您可以为 安装JVM未使用的任何信号 的Java处理程序。这些 信号处理程序类似于本机 处理程序,因为它们在 引发本机系统信号时调用,但它们将始终作为单独的 Java线程运行。本质上,当引发信号处理器可用的 信号时,JVM的 “信号分配器线程”被唤醒 并通知信号。分派器线程然后调用Java 方法来为安装的Java信号处理器创建并启动新的 线程。要编写处理器的Java信号 ,请定义一个类,该类使用sun.misc.Signal.handle() 方法实现sun.misc.SignalHandler接口并通过 注册处理程序。

我还参加了一个讨论这个话题here

+0

oops ...当我发布我的时候没有看到你的答案...我检查了我的ibm和sun jdk6安装,并且两者似乎仍支持此功能。 – 2012-01-03 18:27:05

0

这是可以做到的信号在Java中处理,但它是一种功能,依赖于使用sun.misc。*类这是值得因为他们被认为是内部课程,并且在发布之间进行主题变更,所以谨慎接近。

了这番解释,检查此链接了解更多信息:http://www.ibm.com/developerworks/ibm/library/i-signalhandling/#N102C8

这篇文章是基于java 1.3.1但机制仍然存在于Sun和IBM的JVM 1.6两。

我不知道是否可以使用jni和agentlib在你的jvm中安装一个本地信号处理程序......我从来没有尝试过,并且不得不考虑它。有可能jvm已经拥有了不能被覆盖的信号处理。