Java Shutdown挂钩未运行

jim*_*ont 3 java multithreading

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

我在所有线程中添加了一个Shutdown钩子和一个stopThread()方法(比如MyWorker类中的那个)

问题是,当我按^ CI时,看不到Thread的run方法中的结束消息.这是在后台完成还是我的方法有问题.另外,我应该遵循更好的模式吗?

谢谢

 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
     } 
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*rey 7

当您调用System.exit()或通过信号终止时,它会停止所有现有线程并启动所有关闭挂钩.也就是说,当你挂钩开始时你的所有线程都可能已经死了.

您应该确保资源完全关闭,而不是试图干净地停止线程.

  • 如何从胎面本身处理胎面终止?即调用一些代码进行清理。 (2认同)

Nil*_*dav 7

在某些情况下可能无法执行关机挂钩!

首先要记住的是,无法保证关闭挂钩始终会运行.如果JVM由于某些内部错误而崩溃,那么它可能会在没有机会执行单个指令的情况下崩溃.此外,如果O/S发出SIGKILL(http://en.wikipedia.org/wiki/SIGKILL)信号(Unix/Linux中的kill -9)或TerminateProcess(Windows),则应用程序需要立即终止甚至等待任何清理活动.除了上述内容之外,还可以通过调用Runime.halt()方法来终止JVM而不允许关闭挂钩运行.

当应用程序正常终止时(当所有线程完成或调用System.exit(0)时),将调用关闭挂钩.此外,当JVM由于外部原因(例如用户请求终止(Ctrl + C))而关闭时,由O/S(正常kill命令,不带-9)或操作系统关闭时发出SIGTERM .


Ami*_*nde 5

我想你可以将你的代码转移到ExectuterService

private final ExecutorService pool;
pool = Executors.newFixedThreadPool(poolSize);
pool.execute(Instance of Runnable);
pool.shutdown(); 
Run Code Online (Sandbox Code Playgroud)

ExectuterService.shutdown

启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务.如果已经关闭,调用没有其他影响.