正常关闭 Java 命令行程序的最佳方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1028687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best Way to Gracefully Shutdown a Java Command Line Program
提问by
I'm interested in different approaches to gracefully shutting down a Java command line program. Sending a kill signal is not an option.
我对优雅地关闭 Java 命令行程序的不同方法感兴趣。发送终止信号不是一种选择。
I can think of a few different approaches.
我可以想到几种不同的方法。
- Open a port and wait for a connection. When one is made, gracefully shutdown.
- Watch for a file to be created, then shutdown.
- Read some input from the terminal, such as "execute shutdown".
- 打开一个端口并等待连接。制作完成后,正常关机。
- 观察要创建的文件,然后关闭。
- 从终端读取一些输入,例如“执行关机”。
The third one is not ideal, since there is often program output pumped to the screen. The first one takes too much effort (I'm lazy). Do most programmers use the second option? If not, what else is possible/elegant/simple?
第三个不理想,因为经常有程序输出被泵送到屏幕上。第一个需要太多努力(我很懒惰)。大多数程序员使用第二种选择吗?如果不是,还有什么可能/优雅/简单?
回答by akarnokd
The first two option is simple to implement. You could also use some JMX stuff (I don't know much about that). Tomcat uses the first approach and I applied 1 and 2 in two of my projects.
前两个选项很容易实现。你也可以使用一些 JMX 的东西(我不太了解)。Tomcat 使用第一种方法,我在我的两个项目中应用了 1 和 2。
回答by dfa
you could try to use Runtime.getRuntime().addShutdownHook()
that should satisfy your requisite. In this way you can register an hook to do cleanups, in order to perfom a gracefull shutdown.
你可以尝试使用Runtime.getRuntime().addShutdownHook()
它应该满足你的要求。通过这种方式,您可以注册一个钩子来进行清理,以便执行正常关闭。
EDIT
编辑
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)public void addShutdownHook(Thread hook) Registers a new virtual-machine shutdown hook. The Java virtual machine shuts down in response to two kinds of events:
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)public void addShutdownHook(Thread hook) 注册一个新的虚拟机关闭钩。Java 虚拟机关闭以响应两种事件:
- The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
- The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.
- 程序正常退出,当最后一个非守护线程退出或调用退出(相当于 System.exit)方法时,或
- 虚拟机响应用户中断(例如键入 ^C)或系统范围的事件(例如用户注销或系统关闭)而终止。
回答by akf
you can try something like this:
你可以尝试这样的事情:
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() { /*
my shutdown code here
*/ }
});
edit:
编辑:
the shutdown hook will not perform the shutting down of the app. instead, it gives the developer a way to perform any clean-up that he/she wishes at shutdown.
关闭钩子不会执行应用程序的关闭。相反,它为开发人员提供了一种在关闭时执行他/她希望的任何清理的方法。
from the JavaDoc for Runtime(a good read if you are planning to use this method):
来自 JavaDoc for Runtime(如果您打算使用此方法,请仔细阅读):
A shutdown hook is simply an initialized but unstarted thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently. When all the hooks have finished it will then run all uninvoked finalizers if finalization-on-exit has been enabled. Finally, the virtual machine will halt. ...
关闭钩子只是一个初始化但未启动的线程。当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有已注册的关闭挂钩,并让它们同时运行。当所有钩子都完成后,如果启用了退出时终结,它将运行所有未调用的终结器。最后,虚拟机将停止。...
回答by Dave Webb
The benefit of the second option - checking for a file - over the first - listening on a port - is that you have some possibility of security.
第二个选项的好处 - 检查文件 - 超过第一个 - 侦听端口 - 是您有一定的安全可能性。
You can set the permissions on the directory where the file is created so that only appropriate users can close the program. If you listen on a port any user can connect to it.
您可以对创建文件的目录设置权限,以便只有合适的用户才能关闭程序。如果你监听一个端口,任何用户都可以连接到它。
回答by Jeroen van Bergen
I would suggest to use the shutdown hook. It will allow your program do be controlled using standard OS tools. It also does not need any additional access to external resources (disk, ports, whatever).
我建议使用关闭钩子。它将允许您使用标准操作系统工具控制您的程序。它也不需要对外部资源(磁盘、端口等)的任何额外访问。
回答by toluju
If you wanted to go with the socket version, it is very simple to implement. Here's the code:
如果您想使用套接字版本,则实现起来非常简单。这是代码:
ServerSocket server = new ServerSocket(8080);
System.out.println("Socket listening!");
server.accept();
System.out.println("Connection received!");
You could easily embed this code in a separate thread that you start with your program, and then have it modify global state to initiate shutdown.
您可以轻松地将此代码嵌入到程序启动的单独线程中,然后让它修改全局状态以启动关闭。
回答by Thorbj?rn Ravn Andersen
Consider having a JMX component. Then you can attach with JConsole either locally or over the network, and communicate with your component. Then the component can shut down the program properly.
考虑使用 JMX 组件。然后,您可以在本地或通过网络连接 JConsole,并与您的组件进行通信。然后组件可以正常关闭程序。
With Java 6 u 10 or later, you can do the same with JVisualVM.
使用 Java 6 u 10 或更高版本,您可以使用 JVisualVM 执行相同操作。