优雅地关闭 Java 命令行程序的最佳方法

发布于 2024-07-24 12:04:20 字数 274 浏览 8 评论 0原文

我对优雅地关闭 Java 命令行程序的不同方法感兴趣。 发送终止信号不是一种选择。

我可以想到几种不同的方法。

  1. 打开端口并等待连接。 完成后,优雅地关闭。
  2. 观察要创建的文件,然后关闭。
  3. 从终端读取一些输入,例如“执行关闭”。

第三种方法并不理想,因为经常有程序输出被输出到屏幕上。 第一个需要太多努力(我很懒)。 大多数程序员都使用第二个选项吗? 如果不是,还有什么可能/优雅/简单?

I'm interested in different approaches to gracefully shutting down a Java command line program. Sending a kill signal is not an option.

I can think of a few different approaches.

  1. Open a port and wait for a connection. When one is made, gracefully shutdown.
  2. Watch for a file to be created, then shutdown.
  3. 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

盗心人 2024-07-31 12:04:20

您可以尝试这样的操作:

Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() { /*
       my shutdown code here
    */ }
 });

编辑:

关闭挂钩不会执行应用程序的关闭。 相反,它为开发人员提供了一种在关闭时执行他/她希望的任何清理的方法。

来自 运行时(如果您打算使用此方法,请仔细阅读):

关闭挂钩只是一个已初始化但未启动的线程。 当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有已注册的关闭挂钩,并让它们同时运行。 当所有钩子完成后,如果启用了退出时终结,它将运行所有未调用的终结器。 最后,虚拟机将停止。 ...

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):

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. ...

晚风撩人 2024-07-31 12:04:20

您可以尝试使用 Runtime.getRuntime().addShutdownHook() 来满足您的要求。 通过这种方式,您可以注册一个钩子来进行清理,以便执行正常关闭。

编辑

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)
公共无效addShutdownHook(线程钩子)
注册一个新的虚拟机关闭挂钩。
Java 虚拟机关闭以响应两种事件:

  • 程序正常退出,当最后一个非守护线程退出时或调用 exit(相当于 System.exit)方法时,或者
  • 虚拟机被关闭时响应用户中断(例如键入 ^C)或系统范围的事件(例如用户注销或系统关闭)而终止。

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.

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:

  • 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.
爱已欠费 2024-07-31 12:04:20

与第一个选项(侦听端口)相比,第二个选项(检查文件)的好处是您有一定的安全性。

您可以设置创建文件的目录的权限,以便只有适当的用户才能关闭程序。 如果您侦听某个端口,则任何用户都可以连接到该端口。

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.

百善笑为先 2024-07-31 12:04:20

如果您想使用套接字版本,实现起来非常简单。 代码如下:

ServerSocket server = new ServerSocket(8080);
System.out.println("Socket listening!");
server.accept();
System.out.println("Connection received!");

您可以轻松地将此代码嵌入到与程序一起启动的单独线程中,然后让它修改全局状态以启动关闭。

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.

沉默的熊 2024-07-31 12:04:20

前两个选项很容易实现。 您还可以使用一些 JMX 东西(我对此不太了解)。 Tomcat 使用第一种方法,我在我的两个项目中应用了 1 和 2。

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.

谢绝鈎搭 2024-07-31 12:04:20

考虑使用 JMX 组件。 然后,您可以在本地或通过网络连接 JConsole,并与您的组件进行通信。 然后组件就可以正常关闭程序了。

对于 Java 6 u 10 或更高版本,您可以使用 JVisualVM 执行相同的操作。

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.

With Java 6 u 10 or later, you can do the same with JVisualVM.

风渺 2024-07-31 12:04:20

我建议使用关闭挂钩。 它将允许您的程序使用标准操作系统工具进行控制。 它还不需要对外部资源(磁盘、端口等)进行任何额外的访问。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文