如何停止 Java 应用程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1693041/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 21:38:49  来源:igfitidea点击:

How to stop a java application?

java

提问by Yatendra Goel

I have made a java application and have packed it into an executable jar file. Now a user can start that program from either of the following two ways:

我制作了一个 java 应用程序并将其打包成一个可执行的 jar 文件。现在,用户可以通过以下两种方式之一启动该程序:

  1. Start if from command prompt by executing the following command on the command prompt:

    java -jar "MyJar.jar"

  2. By double clicking on that jar file.

  1. 通过在命令提示符下执行以下命令从命令提示符启动:

    java -jar "MyJar.jar"

  2. 通过双击该 jar 文件。

I want that my client would adopt second approach as it is much easier than the first approach. But the problem with second approach is how to stop application before it has finished?

我希望我的客户采用第二种方法,因为它比第一种方法容易得多。但是第二种方法的问题是如何在应用程序完成之前停止应用程序?

It is a command-line application.

它是一个命令行应用程序。

And no command prompt window appears when a user double clicks on the jar file. So in this case, Will Ctrl + c work?

当用户双击 jar 文件时,不会出现命令提示窗口。那么在这种情况下, Ctrl + c 会起作用吗?

采纳答案by Nivas

Stopping (exiting) the application should be inside the application. Whether it is command line or GUI based, the application developer should write code to exit it (For eg., in a command line application you might have something like Press 5 to exit, Press Esc to Exitetc) and in an application with a GUI, you will have to write code to exit when the window is closed, or an EXITbutton (or others, depending on your application)

停止(退出)应用程序应该在应用程序内部。无论是基于命令行或图形用户界面,应用程序开发人员应该写代码退出它(对于例如,你可能有类似的命令行应用程序Press 5 to exitPress Esc to Exit等等),并结合GUI的应用程序,你将不得不写代码在窗口关闭时退出,或EXIT按钮(或其他按钮,取决于您的应用程序)

Ctrl + Cis KILL the application. This is nota Normal exit. For apps with a GUI, the user would typically (in Windows) go to task manager and end the process (similar ways in other operating systems)

Ctrl + C正在杀死应用程序。这不是正常退出。对于具有 GUI 的应用程序,用户通常会(在 Windows 中)转到任务管理器并结束进程(其他操作系统中的类似方式)

But these are abnormal exits - when the user wants to kill the app when, for instance, the application is no longer responding. Normal exits should be provided by the application (and therefore by the programmer - you)

但这些都是异常退出——例如,当用户想要终止应用程序时,例如,应用程序不再响应。正常退出应该由应用程序提供(因此由程序员 - 你)

回答by Carl Smotricz

If your program is a console mode program and it's doing output, Ctrl-C should be able to kill it.

如果您的程序是控制台模式程序并且它正在执行输出,则 Ctrl-C 应该能够杀死它。

If it's a GUI program, you'll want to give it a button to exit, or at least setting EXIT_ON_CLOSEas the defaultCloseOperationof your main JFrame.

如果它是一个GUI程序,你会想给它一个按钮退出,或者至少设置EXIT_ON_CLOSEdefaultCloseOperation你的主JFrame的。

回答by Maxime ARNSTAMM

ctrl+alt+suppr -> kill the javaw.exe ? :p

ctrl+alt+suppr -> 杀死 javaw.exe ?:p

Or you would have to present a user interface with a stop button (see swing etc)

或者你必须展示一个带有停止按钮的用户界面(见swing等)

回答by Vincent Ramdhanie

It depends on the User Interface. If its a Swing application then you can setDefaulCloseOperation(JFrame.EXIT_ON_CLOSE) on your main Frame. If its a console app and the user is interacting with it then you ask the user to enter a value that indicates to you that they want to stop the app. If yoy are not interacting with the user at all then ctrl-c will have to work.

这取决于用户界面。如果它是一个 Swing 应用程序,那么您可以在主框架上 setDefaulCloseOperation(JFrame.EXIT_ON_CLOSE)。如果它是一个控制台应用程序并且用户正在与之交互,那么您要求用户输入一个值,向您表明他们想要停止该应用程序。如果 yoy 根本没有与用户交互,那么 ctrl-c 将不得不工作。

回答by jitter

Is it a GUI application or commandline.

它是 GUI 应用程序还是命令行。

In first case just handle the window closing event. In second case handle e.g. CTRL + C

在第一种情况下,只需处理窗口关闭事件。在第二种情况下处理例如 CTRL + C

回答by Omnipresent

that depends on what kind of application is it?

这取决于它是什么类型的应用程序?

Is it a swing application? If so, then your app should handle when user clicks the 'close' button. There is a behavior for that. JFrame.close()

它是一个swing应用程序吗?如果是这样,那么您的应用程序应该在用户单击“关闭”按钮时进行处理。有一种行为。JFrame.close()

If it isnt a swing app then ctrl+c will work.

如果它不是 Swing 应用程序,则 ctrl+c 将起作用。

回答by Johannes

"It is a command-line application" you say.. Well you could do it so that when the user hit a button (say esc) he can write short commands to exit, restart etc..

“这是一个命令行应用程序”你说..你可以这样做,这样当用户点击按钮(比如 esc)时,他可以编写简短的命令来退出、重新启动等。

You can do this with KeyListener. When ESC is hit (say that is the button you want the user to hit), you use Scanner on System.in, and you will do a System.exit(0); if the input is "exit".

你可以用KeyListener做到这一点。当按下 ESC 时(假设这是您希望用户按下的按钮),您在 System.in 上使用 Scanner,您将执行 System.exit(0); 如果输入是“退出”。

回答by O. Jones

I've had a similar problem. I have some Java programs that are basically long-running daemon processes. It's nice to be able to stop them and bounce (restart) them.

我遇到了类似的问题。我有一些 Java 程序,它们基本上是长时间运行的守护进程。很高兴能够阻止它们并反弹(重新启动)它们。

I've used two approaches. Both have advantages and disadvantages. One is to set up a signal handler, by putting a function like this in some class of your program (in mine, it's in the class with the main method).

我使用了两种方法。两者都有优点和缺点。一种是设置信号处理程序,通过将这样的函数放在程序的某个类中(在我的程序中,它位于具有 main 方法的类中)。

import sun.misc.Signal;
import sun.misc.SignalHandler;
...
  private static boolean stopNow = false;
  private static boolean restartNow = false;
...
      private static void handleSignals() {
    try {

        Signal.handle(new Signal("TERM"), new SignalHandler() {
            // Signal handler method for CTRL-C and simple kill command.
            public void handle(Signal signal) {
                MyClass.stopNow = true;
            }
        });
    }
    catch (final IllegalArgumentException e) {
        logger.warn("No SIGTERM handling in this instance.");
    }
    try {
        Signal.handle(new Signal("INT"), new SignalHandler() {
            // Signal handler method for kill -INT command
            public void handle(Signal signal) {
                MyClass.stopNow = true;
            }
        });
    }
    catch (final IllegalArgumentException e) {
        logger.debug("No SIGINT handling in this instance.");
    }
    try {

        Signal.handle(new Signal("HUP"), new SignalHandler() {
            // Signal handler method for kill -HUP command
            public void handle(Signal signal) {
                MyClass.restartNow = true;
            }
        });
    }
    catch (final IllegalArgumentException e) {
        logger.warn("No SIGHUP handling in this instance.");
    }
}

This has worked robustly for us in production. You need a genuine Sun JRE for this to work; the one shipped with a typical Linux distro doesn't have the Signal stuff in it. It works OK on Windows too, but you don't get the HUP signal. You do need a shortcut or shellscript to launch this thing.

这在我们的生产中非常有效。你需要一个真正的 Sun JRE 才能工作;随典型 Linux 发行版一起提供的发行版中没有 Signal 内容。它在 Windows 上也可以正常工作,但是您没有收到 HUP 信号。你确实需要一个快捷方式或 shellscript 来启动这个东西。

Also, keep in mind that signal handling is a big fat botch. Don't try to do very much inside your signal handler. You can see that my sample code simply sets static flags. Other parts of my program detect that the flag changed, and shut down. I could have experimented with more complex code inside the signal handler, but I didn't feel like taking on the QA burden.

另外,请记住,信号处理是一个很大的缺陷。不要试图在你的信号处理程序中做太多事情。您可以看到我的示例代码只是设置了静态标志。我的程序的其他部分检测到标志改变,并关闭。我本可以在信号处理程序中试验更复杂的代码,但我不想承担 QA 负担。

The other approach is to structure your program as a Servlet. You'll write a class that extends HttpServlet in this case. Override Servlet.init with a method that starts your worker thread. Likewise, Override Servlet.destroy with a method that shuts yourself down.

另一种方法是将您的程序构建为一个 Servlet。在这种情况下,您将编写一个扩展 HttpServlet 的类。使用启动工作线程的方法覆盖 Servlet.init。同样,使用关闭自己的方法覆盖 Servlet.destroy。

Then you can use a Java EE container server like Tomcat to manage your starting and stopping.

然后你可以使用像Tomcat这样的Java EE容器服务器来管理你的启动和停止。

回答by iTake

I've used socket connection to enable kill of running instance.

我使用套接字连接来启用正在运行的实例的终止。

    //send kill signal to running instance, if any
    try {
        new Socket("localhost", 4000).getInputStream().read(); //block until its done
    } catch (Exception e) { //if no one is listening, we're the only instance
    }
    //start kill listener for self
    new Thread() {

        @Override
        public void run() {
            try {
                ServerSocket serverSocket = new ServerSocket(4000);
                serverSocket.accept();

                //do cleanup here

                serverSocket.close();
            } catch (Exception e) {
            }
            System.exit(0);
        }
    }.start();

回答by Egor Ivanov

You can use this one: exit()

你可以使用这个:exit()

It's possible to predefine all the action before virtual machine is totally stoppeed thus you can save your data and performa all actions to prevent the data loss. I'm not sure it's a good way, because I've just started Java study, but it seems working.

可以在虚拟机完全停止之前预定义所有操作,因此您可以保存数据并执行所有操作以防止数据丢失。我不确定这是一个好方法,因为我刚刚开始学习 Java,但它似乎有效。