Java关闭钩子没有运行
我是Java/threads新手,继承了如下代码。这是一个命令行程序,main()只启动5-6个不同类型的线程,并使用^C退出。我想添加一个关闭钩子来正确关闭所有线程,并按照以下方式进行调整 我在所有线程中添加了一个shutdownhook和一个stopThread()方法(就像MyWorker类中的一个) 问题是,当我按下^C时,我看不到来自线程的run方法的end消息。这是在后台完成的还是我的方法有问题。还有,我是否应该遵循更好的模式 谢谢Java关闭钩子没有运行,java,multithreading,Java,Multithreading,我是Java/threads新手,继承了如下代码。这是一个命令行程序,main()只启动5-6个不同类型的线程,并使用^C退出。我想添加一个关闭钩子来正确关闭所有线程,并按照以下方式进行调整 我在所有线程中添加了一个shutdownhook和一个stopThread()方法(就像MyWorker类中的一个) 问题是,当我按下^C时,我看不到来自线程的run方法的end消息。这是在后台完成的还是我的方法有问题。还有,我是否应该遵循更好的模式 谢谢 public class Main {
public class Main {
public static MyWorker worker1 = new MyWorker();
// .. various other threads here
public static void startThreads() {
worker1.start();
// .. start other threads
}
public static void stopThreads() {
worker1.stopThread();
// .. stop other threads
}
public static void main(String[] args)
throws Exception {
startThreads();
// TODO this needs more work (later)
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
try {
stopThreads();
} catch (Exception exp) {
}
}
});
} }
public class MyWorker extends Thread {
private volatile boolean stop = false;
public void stopThread() {
stop = true;
}
public void run() {
while (!stop) {
// Do stuff here
}
// Print exit message with logger
}
}
当您调用System.exit()或通过信号终止时,它会停止所有现有线程并启动所有关闭挂钩。i、 e.钩子开始时,所有的线都可能会断开
与其尝试干净地停止线程,不如确保资源干净地关闭。尝试将线程设置为守护进程线程 添加构造函数
public MyWorker(boolean isDaemon) {
this.setDaemon(true);
}
或者在调用start之前设置为daemon
worker1.setDaemon(true);
worker1.start();
按Ctrl C并退出时,线程将停止 这里发生的事情是调用
stopThread()
方法,但不要等到线程实际完成后才终止
如果在停止JVM之前在所有线程上调用join()
,您可能会看到“停止日志”
我想你可以把代码改成 启动有序关机,执行以前提交的任务,但不接受新任务。如果调用已经关闭,则调用没有其他效果
在某些情况下可能不会执行关机挂钩强> 首先要记住的是,不能保证关机挂钩总是运行。如果JVM由于某些内部错误而崩溃,那么它可能会在没有机会执行单个指令的情况下崩溃。此外,如果O/S发出SIGKILL()信号(Unix/Linux中为kill-9)或TerminateProcess(Windows),则应用程序需要立即终止,甚至不需要等待任何清理活动。除上述内容外,还可以通过调用Runime.halt()方法来终止JVM,而不允许运行关闭挂钩
当应用程序正常终止时(当所有线程完成时,或当调用System.exit(0)时),将调用关闭挂钩。另外,当JVM由于外部原因关闭时,例如用户请求终止(Ctrl+C)、O/S发出的SIGTERM(正常的kill命令,不带-9),或者当操作系统关闭时。您应该声明
stop
volatile。好的观点(也编辑了问题);)但这并不能解决问题。我已经试过了,但没有成功。我甚至尝试在startThread()/Shutdown hook之后在main()函数上加入它们,我想知道如果在命令行上按Ctrl-C停止程序,这是否有效?如何调用pool.shutdown()?我相信jvm关闭钩子…是的,也可以从关闭钩子中使用,但尽管它表明它大部分时间都会被执行,但它永远不会总是这样。在我的情况下,我想这是行不通的。我有5-6种不同类型的线程:3种生产者、1种消费者和几个其他补充线程。它可能因为其他原因无法工作。它应该适用于不同类型的线程。Java线程实现了可运行的接口。由于其他原因,它可能无法工作。它应该适用于不同类型的线程。Java线程实现可运行的接口。除了Ctrl C之外,您还有其他机制可以关闭吗?也许是命令提示?输入“退出”停止程序。然后调用pool.shutdown(),如何从踏板本身处理踏板终止?i、 调用一些代码进行清理。
public static void stopThreads() {
worker1.stopThread();
// .. stop other threads
for(Thread t: workers) {
t.join();
}
}
private final ExecutorService pool;
pool = Executors.newFixedThreadPool(poolSize);
pool.execute(Instance of Runnable);
pool.shutdown();