我对优雅地关闭Java命令行程序的不同方法感兴趣。发送终止信号不是一种选择。
我可以想到几种不同的方法。
第三个并不理想,因为通常有程序输出泵送到屏幕。第一个需要付出太多努力(我很懒)。大多数程序员使用第二种选择吗?如果没有,还有什么可能/优雅/简单?
答案 0 :(得分:20)
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() { /*
my shutdown code here
*/ }
});
修改强>
关机挂钩不会执行应用程序的关闭。相反,它为开发人员提供了一种方法来执行他/她在关机时所希望的任何清理。
来自JavaDoc for Runtime的(如果您打算使用此方法,请阅读以下内容):
关闭钩子只是一个初始化但未启动的线程。当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有已注册的关闭挂钩,并让它们同时运行。当所有挂钩都完成后,如果启用了finalization-on-exit,它将运行所有未读取的终结器。最后,虚拟机将停止。 ...
答案 1 :(得分:9)
您可以尝试使用符合您要求的Runtime.getRuntime().addShutdownHook()
。通过这种方式,您可以注册一个钩子来执行清理,以便执行正常关闭。
修改强>
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread) public void addShutdownHook(Thread hook) 注册新的虚拟机关闭挂钩。 Java虚拟机关闭以响应两种事件:
答案 2 :(得分:5)
第二个选项 - 检查文件 - 第一个选项 - 监听端口 - 的好处是你有一定的安全可能性。
您可以在创建文件的目录上设置权限,以便只有适当的用户才能关闭该程序。如果您在端口上侦听任何用户都可以连接到它。
答案 3 :(得分:3)
如果您想使用套接字版本,则实现起来非常简单。这是代码:
ServerSocket server = new ServerSocket(8080);
System.out.println("Socket listening!");
server.accept();
System.out.println("Connection received!");
您可以轻松地将此代码嵌入到您从程序开始的单独线程中,然后让它修改全局状态以启动关闭。
答案 4 :(得分:2)
前两个选项很容易实现。你也可以使用一些JMX的东西(我不太了解)。 Tomcat使用第一种方法,我在我的两个项目中应用了1和2。
答案 5 :(得分:1)
考虑使用JMX组件。然后,您可以在本地或通过网络与JConsole连接,并与您的组件进行通信。然后组件可以正常关闭程序。
使用Java 6 u 10或更高版本,您可以对JVisualVM执行相同的操作。
答案 6 :(得分:0)
我建议使用关机钩子。它将允许您的程序使用标准OS工具进行控制。它也不需要任何额外的访问外部资源(磁盘,端口等)。