如何停止java应用程序?

时间:2009-11-07 13:35:41

标签: java

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

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

    java -jar“MyJar.jar”

  2. 双击该jar文件。

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

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

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

10 个答案:

答案 0 :(得分:11)

停止(退出)应用程序应该在应用程序内部。无论是命令行还是基于GUI,应用程序开发人员都应该编写代码来退出它(例如,在命令行应用程序中,您可能有Press 5 to exitPress Esc to Exit等)并在应用程序中使用GUI,您必须编写代码以在窗口关闭时退出,或者EXIT按钮(或其他,取决于您的应用程序)

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

但这些是异常退出 - 当用户想要杀死应用程序时,例如,应用程序不再响应。正常退出应由应用程序提供(因此由程序员 - 您提供)

答案 1 :(得分:5)

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

我用了两种方法。两者都有优点和缺点。一种是设置一个信号处理程序,通过在你的程序的某个类中放置这样的函数(在我的程序中,它使用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.");
    }
}

这对我们的生产起到了很好的作用。你需要一个真正的Sun JRE才能工作;一个典型的Linux发行版附带的那个没有Signal信号。它在Windows上运行正常,但是你没有得到HUP信号。你确实需要一个快捷方式或一个shellcript来启动这个东西。

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

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

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

答案 2 :(得分:2)

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

如果是GUI程序,您需要给它一个退出按钮,或者至少将EXIT_ON_CLOSE设置为主JFrame的defaultCloseOperation

答案 3 :(得分:1)

ctrl + alt + suppr - >杀掉javaw.exe? :P

或者您必须使用停止按钮呈现用户界面(请参阅摆动等)

答案 4 :(得分:1)

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

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

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

是摆动应用吗?如果是这样,那么当用户点击“关闭”按钮时,您的应用就应该处理。有一种行为。 JFrame.close()

如果它不是摇摆应​​用程序,那么ctrl + c将起作用。

答案 7 :(得分:0)

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

您可以使用KeyListener执行此操作。当ESC命中时(比如你希望用户点击的那个按钮),你在System.in上使用Scanner,你会做一个System.exit(0);如果输入是“退出”。

答案 8 :(得分:0)

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

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

答案 9 :(得分:0)

你可以使用这个:exit()

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