1

我有一个用 Java 编写的程序,它使用 3 个线程。IDE(Netbeans)中的一切工作正常,当我杀死它时,它会破坏所有线程。当我从命令行启动它并按 Ctrl-C 时,线程会继续运行。处理这个问题的最佳方法是什么?

它是否会杀死主线程,因为我想在那之后我可以使用标志?

4

6 回答 6

2

您可以在主线程上注册一个关闭挂钩以优雅地清理其他线程。

public static void main(String[] args) {
  Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
      System.out.println("System shutting down");
      // tell your other threads to shut down from here
      // the best way to do this is to set a flag 
      // that they will pick up on and exit gracefully
    }
  });
}
于 2012-07-30T12:03:13.147 回答
1

在我所知道的大多数 Linux 系统上,如果程序在前台,按 control-c 会导致一个中断信号 (SIGINT) 发送到 JVM,该信号会杀死所有线程(无论是否为守护进程)并退出。我在 Mac OSX 和 CentOS Linux 上尝试了这个愚蠢的小程序,使用 control-c 可以正常退出。

这里没有提到的一件事是信号处理程序可能正在捕获中断信号。它们允许您捕获 control-c(和其他信号),以便您可以用它们做一些智能的事情。它们非常依赖于操作系统(当然),如果你捕捉到中断信号(SIGINT 通常由 control-c 发送)并且停止 JVM,你就会遇到问题。

但无论如何,您都可以执行以下操作:

...
MyHandler handler = new MyHandler();
// catch the control-c signal, "TERM" is another common kill signal
Signal.handle(new Signal("INT"), handler);
...

private static class MyHandler implements SignalHandler {
    @Override
    public void handle(Signal arg0) {
        // interrupt your threads
        // clean up stuff
        // set shutdown flags
        // ...
    }
}

同样,我想说捕获中断信号(control-c)而不是关闭 JVM 是一种不好的做法。这可能是您的应用程序的问题。

于 2012-08-01T14:42:28.243 回答
1

1.你可以some loop control mechanism为你的线程使用布尔值。

2. Else try using Daemon threads,因为没有Non-Daemon线程,JVM会被关闭。

通过默认它的 Non-Daemon,但是您可以在调用执行线程的方法之前将线程设置为 Daemon ...start()

The JVM will terminate ONLY when all the non-daemon threads including the Main thread has terminated.

例如:

      Thread t = new Thread(MyClass);
      t.setDaemon(true);
于 2012-07-30T12:01:51.900 回答
0

Java 可执行文件通过生成到 stdout 的线程转储来响应 Windows 上的 ctrl-c(unix 上的 ctrl-\)。您仍然可以在 Windows 上通过 ctrl-break 杀死它。

于 2012-07-30T12:24:00.443 回答
0

它是否会杀死主线程,因为我想在那之后我可以使用标志?

我不知道 Ctrl-C 特别做什么,但是如果你让你的“永久”线程守护线程,你的应用程序应该在所有非守护线程都终止时终止。有关更多详细信息,请参阅Thread文档

于 2012-07-30T11:57:13.347 回答
0

您有一个线程作为主线程,其他线程作为守护线程。

使用 Thread.setDaemon(true)

于 2012-07-30T12:02:31.650 回答