我有一个用 Java 编写的程序,它使用 3 个线程。IDE(Netbeans)中的一切工作正常,当我杀死它时,它会破坏所有线程。当我从命令行启动它并按 Ctrl-C 时,线程会继续运行。处理这个问题的最佳方法是什么?
它是否会杀死主线程,因为我想在那之后我可以使用标志?
我有一个用 Java 编写的程序,它使用 3 个线程。IDE(Netbeans)中的一切工作正常,当我杀死它时,它会破坏所有线程。当我从命令行启动它并按 Ctrl-C 时,线程会继续运行。处理这个问题的最佳方法是什么?
它是否会杀死主线程,因为我想在那之后我可以使用标志?
您可以在主线程上注册一个关闭挂钩以优雅地清理其他线程。
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
}
});
}
在我所知道的大多数 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 是一种不好的做法。这可能是您的应用程序的问题。
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);
Java 可执行文件通过生成到 stdout 的线程转储来响应 Windows 上的 ctrl-c(unix 上的 ctrl-\)。您仍然可以在 Windows 上通过 ctrl-break 杀死它。
它是否会杀死主线程,因为我想在那之后我可以使用标志?
我不知道 Ctrl-C 特别做什么,但是如果你让你的“永久”线程守护线程,你的应用程序应该在所有非守护线程都终止时终止。有关更多详细信息,请参阅Thread
文档。
您有一个线程作为主线程,其他线程作为守护线程。
使用 Thread.setDaemon(true)