Java关闭钩子没有运行

Java关闭钩子没有运行,java,multithreading,Java,Multithreading,我是Java/threads新手,继承了如下代码。这是一个命令行程序,main()只启动5-6个不同类型的线程,并使用^C退出。我想添加一个关闭钩子来正确关闭所有线程,并按照以下方式进行调整 我在所有线程中添加了一个shutdownhook和一个stopThread()方法(就像MyWorker类中的一个) 问题是,当我按下^C时,我看不到来自线程的run方法的end消息。这是在后台完成的还是我的方法有问题。还有,我是否应该遵循更好的模式 谢谢 public class Main {

我是Java/threads新手,继承了如下代码。这是一个命令行程序,main()只启动5-6个不同类型的线程,并使用^C退出。我想添加一个关闭钩子来正确关闭所有线程,并按照以下方式进行调整

我在所有线程中添加了一个shutdownhook和一个stopThread()方法(就像MyWorker类中的一个)

问题是,当我按下^C时,我看不到来自线程的run方法的end消息。这是在后台完成的还是我的方法有问题。还有,我是否应该遵循更好的模式

谢谢

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